home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xigc_v21.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  180.5 KB  |  6,561 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    Goban.c
  7. #    Goban.doc
  8. #    Goban.h
  9. #    GobanP.h
  10. #    Imakefile
  11. #    Makefile.hand
  12. #    Makefile.sun
  13. #    README
  14. #    XIgc.ad
  15. #    blackstone.bm
  16. #    board.c
  17. #    filter.c
  18. #    filter.h
  19. #    igscomm.c
  20. #    igscomm.h
  21. #    patchlevel.h
  22. #    pipes.c
  23. #    sample_xigcrc
  24. #    shared.h
  25. #    sound.note
  26. #    stipple.bm
  27. #    stipple2.bm
  28. #    stonemask.bm
  29. #    whitestone.bm
  30. #    xigc.c
  31. #    xigc.man
  32. # This archive created: Wed Jan  6 23:02:31 1993
  33. export PATH; PATH=/bin:/usr/bin:$PATH
  34. if test -f 'Goban.c'
  35. then
  36.     echo shar: "will not over-write existing file 'Goban.c'"
  37. else
  38. cat << \SHAR_EOF > 'Goban.c'
  39. /* Goban.c
  40.  * S.Coffin     USWAT   7/92
  41.  *
  42.  * adapted from the below
  43.  */
  44.  
  45. /****************************************************************************************************************
  46.  *
  47.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  48.  *
  49.  *  This program is distributed in the hope that it will be useful.
  50.  *  Use and copying of this software and preparation of derivative works
  51.  *  based upon this software are permitted, so long as the following
  52.  *  conditions are met:
  53.  *       o credit to the authors is acknowledged following current
  54.  *         academic behaviour
  55.  *       o no fees or compensation are charged for use, copies, or
  56.  *         access to this software
  57.  *       o this copyright notice is included intact.
  58.  *  This software is made available AS IS, and no warranty is made about 
  59.  *  the software or its performance. 
  60.  * 
  61.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  62.  *  Send them to    dumesnil@etca.fr   or to:
  63.  *       
  64.  *       Antoine de Maricourt
  65.  *       ETCA CREA-SP
  66.  *       16 bis, avenue Prieur de la Cote d'Or
  67.  *       94114 Arcueil Cedex
  68.  *       France
  69.  */
  70.  
  71. #include <X11/IntrinsicP.h>
  72. #include <X11/StringDefs.h>
  73. #include <X11/Xlib.h>
  74. #include <X11/cursorfont.h>
  75.  
  76. #include "GobanP.h"
  77.  
  78. #include "whitestone.bm"
  79. #include "blackstone.bm"
  80. #include "stonemask.bm"
  81. #include "stipple.bm"
  82. #include <stdio.h>
  83.  
  84. #define offset(field) XtOffset (GobanWidget, goban.field)
  85. static Position lastx = (-1), lasty;
  86. static GbPointState lastcolor;
  87. extern char stippleflag;
  88.  
  89. static XtResource resources[] = {
  90.   { XtNautoRedisplay,
  91.     XtCAutoRedisplay,
  92.     XtRBoolean,
  93.     sizeof (Boolean),
  94.     offset (auto_redisplay),
  95.     XtRImmediate,
  96.     (caddr_t) TRUE },
  97.   { XtNviewBottom,
  98.     XtCPosition,
  99.     XtRPosition,
  100.     sizeof (Position),
  101.     offset (bottom),
  102.     XtRImmediate,
  103.     (caddr_t) 1 },
  104.   { XtNcursor,
  105.     XtCCursor,
  106.     XtRInt,
  107.     sizeof (int),
  108.     offset (cursor),
  109.     XtRImmediate,
  110.     (caddr_t) GbCBlackStone },
  111.   { XtNfont,
  112.     XtCFont,
  113.     XtRFontStruct,
  114.     sizeof (XFontStruct *),
  115.     offset (font),
  116.     XtRString,
  117.     "fixed" },
  118.   { XtNforeground,
  119.     XtCForeground,
  120.     XtRPixel,
  121.     sizeof (Pixel),
  122.     offset (foreground),
  123.     XtRString,
  124.     XtDefaultForeground },
  125.   { XtNgameSize,
  126.     XtCSize,
  127.     XtRDimension,
  128.     sizeof (Dimension),
  129.     offset (game_size),
  130.     XtRImmediate,
  131.     (caddr_t) 19 },
  132.   { XtNviewLeft,
  133.     XtCPosition,
  134.     XtRPosition,
  135.     sizeof (Position),
  136.     offset (left),
  137.     XtRImmediate,
  138.     (caddr_t) 1 },
  139.   { XtNdisplayCoordinates,
  140.     XtCDisplayCoordinates,
  141.     XtRBoolean,
  142.     sizeof (Boolean),
  143.     offset (display_coordinates),
  144.     XtRImmediate,
  145.     (caddr_t) TRUE },
  146.   { XtNpointSize,
  147.     XtCSize,
  148.     XtRDimension,
  149.     sizeof (Dimension),
  150.     offset (point_size),
  151.     XtRImmediate,
  152.     (caddr_t) 26 },
  153.   { XtNstipple,
  154.     XtCSize,
  155.     XtRBoolean,
  156.     sizeof (Boolean),
  157.     offset (stipple),
  158.     XtRImmediate,
  159.     (caddr_t) FALSE },
  160.   { XtNviewRight,
  161.     XtCPosition,
  162.     XtRPosition,
  163.     sizeof (Position),
  164.     offset (right),
  165.     XtRImmediate,
  166.     (caddr_t) 19 },
  167.   { XtNviewTop,
  168.     XtCPosition,
  169.     XtRPosition,
  170.     sizeof (Position), 
  171.     offset (top),
  172.     XtRImmediate,
  173.     (caddr_t) 19 },
  174.   { XtNwhiteStoneForeground,
  175.     XtCForeground,
  176.     XtRPixel,
  177.     sizeof (Pixel),
  178.     offset (white_fg),
  179.     XtRString,
  180.     "black" },
  181.   { XtNwhiteStoneBackground,
  182.     XtCBackground,
  183.     XtRPixel,
  184.     sizeof (Pixel),
  185.     offset (white_bg),
  186.     XtRString,
  187.     "white" },
  188.   { XtNwhiteStoneBorder,
  189.     XtCBorderColor,
  190.     XtRPixel,
  191.     sizeof (Pixel),
  192.     offset (white_bd),
  193.     XtRString,
  194.     "black" },
  195.   { XtNblackStoneForeground,
  196.     XtCForeground,
  197.     XtRPixel,
  198.     sizeof (Pixel),
  199.     offset (black_fg),
  200.     XtRString,
  201.     "white" },
  202.   { XtNblackStoneBackground,
  203.     XtCBackground,
  204.     XtRPixel,
  205.     sizeof (Pixel),
  206.     offset (black_bg),
  207.     XtRString,
  208.     "black" },
  209.   { XtNblackStoneBorder,
  210.     XtCBorderColor,
  211.     XtRPixel,
  212.     sizeof (Pixel),
  213.     offset (black_bd),
  214.     XtRString,
  215.     "black" },
  216. };
  217.  
  218. static void    ClassInitialize ();
  219. static void    Initialize      ();
  220. static void    Redisplay       ();
  221. static void    Realize         ();
  222. static void    Destroy         ();
  223. static void    Resize          ();
  224. static void    DrawPoint       ();
  225. static Boolean SetValues       ();
  226.  
  227. GobanClassRec gobanClassRec = {
  228.   { /* core fields */
  229.     /* superclass        */    (WidgetClass) &widgetClassRec,
  230.     /* class_name        */    "Goban",
  231.     /* widget_size        */    sizeof (GobanRec),
  232.     /* class_initialize        */    ClassInitialize,
  233.     /* class_part_initialize    */    NULL,
  234.     /* class_inited        */    FALSE,
  235.     /* initialize        */    Initialize,
  236.     /* initialize_hook        */    NULL,
  237.     /* realize            */    Realize,
  238.     /* actions            */    NULL,
  239.     /* num_actions        */    0,
  240.     /* resources        */    resources,
  241.     /* num_resources        */    XtNumber (resources),
  242.     /* xrm_class        */    NULLQUARK,
  243.     /* compress_motion        */    TRUE,
  244.     /* compress_exposure    */    TRUE,
  245.     /* compress_enterleave    */    TRUE,
  246.     /* visible_interest        */    FALSE,
  247.     /* destroy            */    Destroy,
  248.     /* resize            */    Resize,
  249.     /* expose            */    Redisplay,
  250.     /* set_values        */    SetValues,
  251.     /* set_values_hook        */    NULL,
  252.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  253.     /* get_values_hook        */    NULL,
  254.     /* accept_focus        */    NULL,
  255.     /* version            */    XtVersion,
  256.     /* callback_private        */    NULL,
  257.     /* tm_table            */    NULL,
  258.     /* query_geometry        */    XtInheritQueryGeometry,
  259.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  260.     /* extension        */    NULL
  261.   }
  262. };
  263.  
  264. WidgetClass gobanWidgetClass = (WidgetClass) &gobanClassRec;
  265.  
  266. /****************************************************************************************************************
  267.  */
  268.  
  269. void GbRedisplayBoard (w)
  270. Widget w;
  271. {
  272.   GobanWidget gw      = (GobanWidget) w;
  273.   Dimension   width   = w->core.width;
  274.   Dimension   height  = w->core.height;
  275.  
  276.   if (XtIsRealized (w))
  277.     XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, 0, 0, width, height, 0, 0);
  278. }
  279.  
  280. /****************************************************************************************************************
  281.  */
  282.  
  283. void GbClearBoard (w)
  284. Widget w;
  285. {
  286.   GobanWidget gw        = (GobanWidget) w;
  287.   Boolean     redisplay = gw->goban.auto_redisplay;
  288.   Position    x;
  289.   Position    y;
  290.  
  291.   gw->goban.auto_redisplay = FALSE;
  292.  
  293.   for (x = 1; x <= (Position)gw->goban.game_size; x++)
  294.     for (y = 1; y <= (Position)gw->goban.game_size; y++)
  295.       GbSetPoint( w, x, y, GbEmptyPoint, TRUE );
  296.  
  297.   gw->goban.auto_redisplay = redisplay;
  298.  
  299.   if( redisplay == TRUE ) GbRedisplayBoard( w );
  300. }
  301.  
  302. /****************************************************************************************************************
  303.  */
  304.  
  305. void GbClearMarks (w)
  306. Widget w;
  307. {
  308.   GobanWidget gw        = (GobanWidget) w;
  309.   Boolean     redisplay = gw->goban.auto_redisplay;
  310.   Position    x;
  311.   Position    y;
  312.  
  313.   gw->goban.auto_redisplay = FALSE;
  314.  
  315.   for (x = 1; x <= (Position)gw->goban.game_size; x++)
  316.     for (y = 1; y <= (Position)gw->goban.game_size; y++) {
  317.  
  318.       gw->goban.points[x][y].mark1 = 0;
  319.       gw->goban.points[x][y].mark2 = 0;
  320.       gw->goban.points[x][y].num   = 0;
  321.     
  322.       if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
  323.     if (gw->goban.points[x][y].free == 1)
  324.       DrawPoint (w, x, y, GbEmptyPoint, FALSE);
  325.     else
  326.       if (gw->goban.points[x][y].black == 1)
  327.         DrawPoint (w, x, y, GbBlackStone, FALSE);
  328.       else
  329.         DrawPoint (w, x, y, GbWhiteStone, FALSE);
  330.     }
  331.  
  332.   gw->goban.auto_redisplay = redisplay;
  333.  
  334.   if (redisplay == TRUE)
  335.     GbRedisplayBoard (w);
  336. }
  337.  
  338. /****************************************************************************************************************
  339.  */
  340.  
  341. /* ARGSUSED */
  342.  
  343. void GbSetPoint( w, x, y, color, flag )
  344. Widget       w;
  345. Position     x;
  346. Position     y;
  347. GbPointState color;
  348. unsigned char flag;
  349. {
  350.   GobanWidget gw = (GobanWidget) w;
  351.  
  352.   if (x >= 1 && y >= 1 && x <= (Position)gw->goban.game_size &&
  353.         y <= (Position)gw->goban.game_size) {
  354.     switch (color) {
  355.  
  356.     case GbBlackStone :
  357.       gw->goban.points[x][y].free  = 0;
  358.       gw->goban.points[x][y].black = 1;
  359.       break;
  360.  
  361.     case GbWhiteStone :
  362.       gw->goban.points[x][y].free  = 0;
  363.       gw->goban.points[x][y].black = 0;
  364.       break;
  365.  
  366.     case GbEmptyPoint :
  367.       gw->goban.points[x][y].free  = 1;
  368.       break;
  369.     }
  370.     
  371.     gw->goban.points[x][y].num   = 0;
  372.     gw->goban.points[x][y].mark1 = 0;
  373.     gw->goban.points[x][y].mark2 = 0;
  374.  
  375.     if( x >= gw->goban.left && y >= gw->goban.bottom &&
  376.     x <= gw->goban.right && y <= gw->goban.top ) {
  377.       if( lastx >= 0 ) DrawPoint( w, lastx, lasty, lastcolor, FALSE );
  378.       DrawPoint( w, x, y, color, flag );
  379.       lastx = x;
  380.       lasty = y;
  381.       lastcolor = color;
  382.     }
  383.   }
  384. }
  385.  
  386. /****************************************************************************************************************
  387.  */
  388.  
  389. /* ARGSUSED */
  390.  
  391. Boolean GbGetPositionFromStone (w, x, y)
  392. GobanWidget   w;
  393. Position     *x;
  394. Position     *y;
  395. {
  396.   if (*x >= w->goban.left && *y >= w->goban.bottom && *x <= w->goban.right && *y <= w->goban.top) {
  397.     
  398.     *x = (Position)((w->goban.x_offset + w->goban.point_size * *x) * (Position)2 + w->goban.point_size) / (Position)2;
  399.     *y = (Position)((w->goban.y_offset - w->goban.point_size * *y) * (Position)2 + w->goban.point_size) / (Position)2;
  400.     
  401.     return TRUE;
  402.   }
  403.   
  404.   else 
  405.     return FALSE;
  406. }
  407.  
  408. /****************************************************************************************************************
  409.  */
  410.  
  411. /* ARGSUSED */
  412.  
  413. Boolean GbGetStoneFromPosition (w, x, y)
  414. Widget     w;
  415. Position  *x;
  416. Position  *y;
  417. {
  418.   GobanWidget gw         = (GobanWidget) w;
  419.   Dimension   point_size = gw->goban.point_size;
  420.   Position    xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  421.   Position    ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  422.   Position    xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  423.   Position    ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  424.  
  425.   if (*x > xmin && *x < xmax && *y > ymin && *y < ymax) {
  426.  
  427.     *x = (Position)(*x - gw->goban.x_offset - 1) / (Position)point_size;
  428.     *y = (Position)(gw->goban.y_offset - *y + point_size + 1) / (Position)point_size;
  429.  
  430.     return TRUE;
  431.   }
  432.  
  433.   return FALSE;
  434. }
  435.  
  436. /****************************************************************************************************************
  437.  */
  438.  
  439. void GbSetNum (w, x, y, num)
  440. Widget      w;
  441. Position    x;
  442. Position    y;
  443. int         num;
  444. {
  445.   GobanWidget  gw      = (GobanWidget) w;
  446.   Display     *display = XtDisplay (w);
  447.   GC           draw_gc;
  448.   GC           undraw_gc;
  449.   XCharStruct  extent;
  450.   XExposeEvent event;
  451.   int          ascent;
  452.   int          descent;
  453.   int          direction;
  454.   int          X;
  455.   int          Y;
  456.   char         s[3];
  457.   int          len = 0;
  458.  
  459.   if (num >= 0 && num <= 999 && (int)x >= 1 && (int)y >= 1  && (int)x <= (int)gw->goban.game_size && (int)y <= (int)gw->goban.game_size) {
  460.     
  461.     gw->goban.points[x][y].num   = num;
  462.     gw->goban.points[x][y].mark1 = 0;
  463.     gw->goban.points[x][y].mark2 = 0;
  464.     
  465.     if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
  466.       
  467.       if (gw->goban.points[x][y].free == 0) {
  468.     
  469.     if (num == 0) {
  470.       if (gw->goban.points[x][y].black == 1)
  471.         DrawPoint (w, x, y, GbBlackStone, FALSE);
  472.       else
  473.         DrawPoint (w, x, y, GbWhiteStone, FALSE);
  474.     }
  475.     
  476.     else {
  477.       if (gw->goban.points[x][y].black == 1) {
  478.         draw_gc   = gw->goban.black_fg_gc;
  479.         undraw_gc = gw->goban.black_bg_gc;
  480.       } else {
  481.         draw_gc   = gw->goban.white_fg_gc;
  482.         undraw_gc = gw->goban.white_bg_gc;
  483.       }
  484.       
  485.       X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
  486.       Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
  487.       
  488.       if (num > 99)
  489.         s[len++] = '0' + (num % 1000) / 100;
  490.       if (num > 9)
  491.         s[len++] = '0' + (num % 100) / 10;
  492.       s[len++] = '0' + num % 10;
  493.       
  494.       XQueryTextExtents (display, XGContextFromGC (draw_gc),
  495.                  s, len, &direction, &ascent, &descent, &extent);
  496.       
  497.       if (extent.width + extent.descent + extent.ascent < (int)gw->goban.point_size - 1) {
  498.         XFillArc (display, gw->goban.picture, undraw_gc, 
  499.               (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2, 
  500.               (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4, 
  501.               0, 360 * 64);
  502.         XDrawString (display, gw->goban.picture, draw_gc,
  503.              (X - extent.width) / 2 - extent.lbearing + 1, 
  504.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  505.       }
  506.     
  507.       if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  508.         event.x      = (int)(X - gw->goban.point_size) / 2;
  509.         event.y      = (int)(Y - gw->goban.point_size) / 2;
  510.         event.width  = gw->goban.point_size;
  511.         event.height = gw->goban.point_size;
  512.         
  513.         Redisplay (w, &event, (Region) NULL);
  514.       }
  515.     }
  516.       }
  517.     }
  518.   }
  519. }
  520.  
  521. /****************************************************************************************************************
  522.  */
  523.  
  524. void GbSetMark( w, x, y, c1, c2 )
  525.     Widget        w;
  526.     Position      x;
  527.     Position      y;
  528.     unsigned char c1;
  529.     unsigned char c2;
  530. {
  531.   GobanWidget  gw      = (GobanWidget) w;
  532.   Display     *display = XtDisplay (w);
  533.   int          len     = 0;
  534.   XCharStruct  extent;
  535.   XExposeEvent event;
  536.   int          ascent;
  537.   int          descent;
  538.   int          direction;
  539.   int          X;
  540.   int          Y;
  541.   int          radius;
  542.   char         s[2];
  543.   XSegment     segment[4];
  544.   GC           mark_gc;
  545.   GC           erase_gc;
  546.  
  547.   if( (int)x >= 1 &&
  548.       (int)y >= 1 &&
  549.       (int)x <= (int)gw->goban.game_size &&
  550.       (int)y <= (int)gw->goban.game_size) {
  551.    
  552.     if( c1 != 0 || c2 != 0 ) GbSetMark( w, x, y, 0, 0 );
  553.      
  554.     gw->goban.points[x][y].mark1 = c1;
  555.     gw->goban.points[x][y].mark2 = c2;
  556.     gw->goban.points[x][y].num   = 0;
  557.  
  558.     if( x >= gw->goban.left && y >= gw->goban.bottom &&
  559.     x <= gw->goban.right && y <= gw->goban.top) {
  560.       
  561.       if (c1 == 0 && c2 == 0) {
  562.     if (gw->goban.points[x][y].free == 0)
  563.       if (gw->goban.points[x][y].black == 1)
  564.         DrawPoint( w, x, y, GbBlackStone, FALSE );
  565.       else
  566.         DrawPoint( w, x, y, GbWhiteStone, FALSE );
  567.     else
  568.       DrawPoint( w, x, y, GbEmptyPoint, FALSE );
  569.       }
  570.       
  571.       else {
  572.     X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 +
  573.             gw->goban.point_size;
  574.     Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 +
  575.             gw->goban.point_size;
  576.               
  577.     if (gw->goban.points[x][y].free == 0)
  578.       if (gw->goban.points[x][y].black == 1) {
  579.         mark_gc  = gw->goban.black_fg_gc;
  580.         erase_gc = gw->goban.black_bg_gc;
  581.       }
  582.       else {
  583.         mark_gc  = gw->goban.white_fg_gc;
  584.         erase_gc = gw->goban.white_bg_gc;
  585.       }
  586.  
  587.     else {
  588.       mark_gc  = gw->goban.foreground_gc;
  589.       erase_gc = gw->goban.background_gc;
  590.     }
  591.     
  592.     if (c1 == 0) {
  593.       radius = 10 * (int)gw->goban.point_size / 15;
  594.       
  595.       if (gw->goban.points[x][y].free == 0)
  596.           XFillArc (display, gw->goban.picture, erase_gc, 
  597.             (int) (X - gw->goban.point_size) / 2 + 2,
  598.             (int) (Y - gw->goban.point_size) / 2 + 2, 
  599.             (unsigned int) gw->goban.point_size - 4,
  600.             (unsigned int) gw->goban.point_size - 4, 
  601.             0, 360 * 64);
  602.       else
  603.         XFillArc (display, gw->goban.picture, erase_gc,
  604.               (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  605.               (unsigned int) radius, (unsigned int) radius, 
  606.               0, 360 * 64);
  607.  
  608.       switch( c2 ) {
  609.         
  610.       case GbMTriangleMark :
  611.         radius -= 4;
  612.  
  613.         segment[0].x1 = (short) X / 2;
  614.         segment[0].x2 = (short) (X / 2 + (86 * radius + 100) / 200);
  615.         segment[0].y1 = (short) (Y / 2 - (radius - 1) / 2);
  616.         segment[0].y2 = (short) (Y / 2 + (radius + 4) / 4);
  617.         
  618.         segment[1].x1 = (short) segment[0].x2;
  619.         segment[1].x2 = (short) (X / 2 - (86 * radius + 100) / 200);
  620.         segment[1].y1 = (short) segment[0].y2;
  621.         segment[1].y2 = (short) (Y / 2 + (radius + 4) / 4);
  622.         
  623.         segment[2].x1 = (short) segment[1].x2;
  624.         segment[2].x2 = (short) segment[0].x1;
  625.         segment[2].y1 = (short) segment[1].y2;
  626.         segment[2].y2 = (short) segment[0].y1;
  627.  
  628.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 3);
  629.         break;
  630.  
  631.       case GbMSquareMark  :
  632.         radius = 10 * radius / 14 - 2;
  633.         
  634.         XDrawRectangle (display, gw->goban.picture, mark_gc, 
  635.                 (X - radius) / 2, (Y - radius) / 2, 
  636.                 (unsigned int) radius, (unsigned int) radius);
  637.         break;
  638.     
  639.       case GbMDCrossMark  :
  640.         radius = 10 * radius / 14 - 2;
  641.  
  642.         segment[0].x1 = (short) (X - radius) / 2;
  643.         segment[0].x2 = (short) segment[0].x1    + radius;
  644.         segment[0].y1 = (short) (Y - radius) / 2;
  645.         segment[0].y2 = (short) segment[0].y1    + radius;
  646.  
  647.         segment[1].x1 = (short) (X - radius) / 2 + radius;
  648.         segment[1].x2 = (short) segment[1].x1    - radius;
  649.         segment[1].y1 = (short) (Y - radius) / 2;
  650.         segment[1].y2 = (short) segment[1].y1    + radius;
  651.         
  652.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  653.         break;
  654.         
  655.       case GbMVCrossMark  :
  656.         radius -= 4;
  657.  
  658.         segment[0].x1 = (short) X / 2;
  659.         segment[0].x2 = (short) segment[0].x1;
  660.         segment[0].y1 = (short) (Y - radius) / 2;
  661.         segment[0].y2 = (short) segment[0].y1 + radius;
  662.  
  663.         segment[1].x1 = (short) (X - radius) / 2;
  664.         segment[1].x2 = (short) segment[1].x1 + radius;
  665.         segment[1].y1 = (short) Y / 2;
  666.         segment[1].y2 = (short) segment[1].y1;
  667.         
  668.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
  669.         break;
  670.  
  671.       case GbMDiamondMark :
  672.         radius -= 4;
  673.  
  674.         segment[0].x1 = (short) X / 2;
  675.         segment[0].x2 = (short) segment[0].x1 + radius / 2;
  676.         segment[0].y1 = (short) (Y - radius) / 2;
  677.         segment[0].y2 = (short) segment[0].y1 + radius / 2;
  678.  
  679.         segment[1].x1 = (short) segment[0].x2;
  680.         segment[1].x2 = (short) segment[0].x1;
  681.         segment[1].y1 = (short) segment[0].y2;
  682.         segment[1].y2 = (short) segment[1].y1 + radius / 2;
  683.         
  684.         segment[2].x1 = (short) segment[1].x2;
  685.         segment[2].x2 = (short) segment[2].x1 - radius / 2;
  686.         segment[2].y1 = (short) segment[1].y2;
  687.         segment[2].y2 = (short) segment[1].y1;
  688.         
  689.         segment[3].x1 = (short) segment[2].x2;
  690.         segment[3].x2 = (short) segment[0].x1;
  691.         segment[3].y1 = (short) segment[2].y2;
  692.         segment[3].y2 = (short) segment[0].y1;
  693.         
  694.         XDrawSegments (display, gw->goban.picture, mark_gc, segment, 4);
  695.         break;
  696.       }
  697.     }
  698.     
  699.     else {
  700.       s[len++] = c1;
  701.       if( c2 != 0 ) s[len++] = c2;
  702.       
  703.       XQueryTextExtents (display, XGContextFromGC (mark_gc), s, len,
  704.                 &direction, &ascent, &descent, &extent);
  705.       
  706.       radius = extent.width + extent.descent + extent.ascent;
  707.       
  708.       if (radius < (int)gw->goban.point_size - 1) {
  709.         if (gw->goban.points[x][y].free == 0)
  710.           XFillArc (display, gw->goban.picture, erase_gc, 
  711.             (int) (X - gw->goban.point_size) / 2 + 2,
  712.             (int) (Y - gw->goban.point_size) / 2 + 2, 
  713.             (unsigned int) gw->goban.point_size - 4,
  714.             (unsigned int) gw->goban.point_size - 4, 
  715.             0, 360 * 64);
  716.         else
  717.           XFillArc (display, gw->goban.picture, erase_gc,
  718.             (int) (X - radius) / 2, (int) (Y - radius) / 2, 
  719.             (unsigned int) radius, (unsigned int) radius, 
  720.             0, 360 * 64);
  721.         
  722.         XDrawString (display, gw->goban.picture, mark_gc,
  723.              (X - extent.width) / 2 - extent.lbearing + 1, 
  724.              (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
  725.       }
  726.     }
  727.       
  728.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  729.       event.x      = (int)(X - gw->goban.point_size) / 2;
  730.       event.y      = (int)(Y - gw->goban.point_size) / 2;
  731.       event.width  = gw->goban.point_size;
  732.       event.height = gw->goban.point_size;
  733.       
  734.       Redisplay (w, &event, (Region) NULL);
  735.     }
  736.       }
  737.     }
  738.   }
  739. }
  740.  
  741. /****************************************************************************************************************
  742.  */
  743.  
  744. /* ARGSUSED */
  745.  
  746. static void Redisplay (w, event, region)
  747. Widget        w;
  748. XExposeEvent *event;
  749. Region        region;
  750. {
  751.   GobanWidget gw     = (GobanWidget) w;
  752.   Position    x      = event->x;
  753.   Position    y      = event->y;
  754.   Dimension   width  = event->width;
  755.   Dimension   height = event->height;
  756.  
  757.   XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, x, y, width, height, x, y);
  758. }
  759.  
  760. /****************************************************************************************************************
  761.  */
  762.  
  763. /* ARGSUSED */
  764.  
  765. static void CvtStringToCursor (args, num_args, fromVal, toVal)
  766. XrmValuePtr   args;        /* unused */
  767. Cardinal     *num_args;    /* unused */
  768. XrmValuePtr   fromVal;
  769. XrmValuePtr   toVal;
  770. {
  771.   static int       cursor;
  772.   static XrmQuark  QWhiteStone;
  773.   static XrmQuark  QBlackStone;
  774.   XrmQuark         quark;
  775.   char             lowerName[256];
  776.   static Boolean   inited = FALSE;
  777.     
  778.   if (inited == FALSE) {
  779.     QWhiteStone  = XrmStringToQuark (XtEgbWhiteStone);
  780.     QBlackStone  = XrmStringToQuark (XtEgbBlackStone);
  781.     inited       = TRUE;
  782.   }
  783.  
  784.   XmuCopyISOLatin1Lowered  (lowerName, (String) fromVal->addr);
  785.   quark = XrmStringToQuark (lowerName);
  786.  
  787.   if (quark == QWhiteStone)
  788.     cursor = GbCWhiteStone;
  789.   else if (quark == QBlackStone)       
  790.     cursor = GbCBlackStone;
  791.   else {
  792.     toVal->size = 0;
  793.     toVal->addr = NULL;
  794.     return;
  795.   }
  796.  
  797.   toVal->size = sizeof (cursor);
  798.   toVal->addr = (caddr_t) &cursor;
  799. }
  800.  
  801. /****************************************************************************************************************
  802.  */
  803.  
  804. static void ClassInitialize()
  805. {
  806.   XtAddConverter (XtRString, XtRInt, (XtConverter) CvtStringToCursor, NULL, 0);
  807. }
  808.  
  809. /****************************************************************************************************************
  810.  */
  811.  
  812. static void InitializePixmap (w)
  813. Widget w;
  814. {
  815.   GobanWidget  gw      = (GobanWidget) w;
  816.   Display     *display = XtDisplay (w);
  817.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  818.   Dimension    width   = w->core.width;
  819.   Dimension    height  = w->core.height;
  820.  
  821.   gw->goban.board   = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  822.   gw->goban.picture = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
  823. }
  824.  
  825. /****************************************************************************************************************
  826.  */
  827.  
  828. static void InitializeGC (w)
  829. Widget w;
  830. {
  831.   GobanWidget  gw      = (GobanWidget) w;
  832.   Display     *display = XtDisplay (w);
  833.   XtGCMask     mask    = GCForeground | GCBackground | GCFont;
  834.   XGCValues    values;
  835.  
  836.   values.font             = gw->goban.font->fid;
  837.   values.background       = w->core.background_pixel;
  838.  
  839.   values.foreground       = gw->goban.white_fg;
  840.   gw->goban.white_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  841.   values.foreground       = gw->goban.white_bg;
  842.   gw->goban.white_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  843.   values.foreground       = gw->goban.white_bd;
  844.   gw->goban.white_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  845.  
  846.   values.foreground       = gw->goban.black_fg;
  847.   gw->goban.black_fg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  848.   values.foreground       = gw->goban.black_bg;
  849.   gw->goban.black_bg_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  850.   values.foreground       = gw->goban.black_bd;
  851.   gw->goban.black_bd_gc   = XCreateGC  (display, gw->goban.picture, mask, &values);
  852.  
  853.   values.foreground       = gw->goban.foreground;
  854.   gw->goban.foreground_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  855.   gw->goban.copy_gc       = XCreateGC  (display, gw->goban.picture, (XtGCMask) 0, (XGCValues *) NULL);
  856.  
  857.   if( !stippleflag ) {
  858.     if( gw->goban.stipple ) stippleflag = TRUE;
  859.   }
  860.   else {
  861.     if( gw->goban.stipple ) stippleflag = FALSE;
  862.   }
  863.  
  864.   if( stippleflag ) {
  865.     values.stipple           = XCreatePixmapFromBitmapData (display,
  866.                 gw->goban.picture,
  867.                 (char *)stipple_bits, stipple_width,
  868.                 stipple_height,
  869.                 BlackPixel (display, DefaultScreen (display)),
  870.                 WhitePixel (display, DefaultScreen (display)),
  871.                 1);
  872.     values.fill_style     = FillOpaqueStippled;
  873.     mask                 |= GCStipple | GCFillStyle;
  874.   }
  875.  
  876.   values.foreground       = w->core.background_pixel;
  877.   values.background       = gw->goban.foreground;
  878.   gw->goban.background_gc = XCreateGC  (display, gw->goban.picture, mask, &values);
  879. }
  880.  
  881. /*******************************************************************/ 
  882. static void InitializeCursor (w)
  883. Widget w;
  884. {
  885.   GobanWidget  gw      = (GobanWidget) w;
  886.   Display     *display = XtDisplay (w);
  887.   Drawable     window  = RootWindowOfScreen (XtScreen (w));
  888.   Pixel        black   = BlackPixel (display, DefaultScreen (display));
  889.   Pixel        white   = WhitePixel (display, DefaultScreen (display));
  890.  
  891.   static XColor black_color = { 0,    0,     0,     0  };  /* black */
  892.   static XColor white_color = { 0, 65535, 65535, 65535 };  /* white */
  893.  
  894.   /* Some teminals invert the mask with BlackPixel and WhitePixel     */
  895.   /* should use black and white instead of 1 and 0 but depth is 1 ... */
  896.   /* will probably have trouble with some special colormaps           */
  897.  
  898.   gw->goban.white_stone = XCreatePixmapFromBitmapData
  899.     (display, window, (char *)whitestone_bits, whitestone_width, whitestone_height, 1, 0, 1);
  900.   gw->goban.black_stone = XCreatePixmapFromBitmapData
  901.     (display, window, (char *)blackstone_bits, blackstone_width, blackstone_height, 1, 0, 1);
  902.   gw->goban.mouse_mask  = XCreatePixmapFromBitmapData
  903.     (display, window, (char *)stonemask_bits , stonemask_width , stonemask_height , 1, 0, 1);
  904.  
  905.   gw->goban.white_cursor = 
  906.     XCreatePixmapCursor (display, gw->goban.white_stone, gw->goban.mouse_mask, 
  907.              &black_color, &white_color, whitestone_x_hot, whitestone_y_hot);
  908.   gw->goban.black_cursor = 
  909.     XCreatePixmapCursor (display, gw->goban.black_stone, gw->goban.mouse_mask, 
  910.              &black_color, &white_color, blackstone_x_hot, blackstone_y_hot);
  911.  
  912.   gw->goban.font_cursor  = XCreateFontCursor (display, XC_question_arrow);
  913. }
  914.   
  915. /****************************************************************************************************************
  916.  */
  917.  
  918. static void DestroyPixmap (w)
  919. Widget w;
  920. {
  921.   GobanWidget  gw      = (GobanWidget) w;
  922.   Display     *display = XtDisplay (w);
  923.  
  924.   XFreePixmap (display, gw->goban.picture);
  925.   XFreePixmap (display, gw->goban.board  );
  926. }
  927.  
  928. /****************************************************************************************************************
  929.  */
  930.  
  931. static void DestroyGC (w)
  932. Widget w;
  933. {
  934.   GobanWidget  gw      = (GobanWidget) w;
  935.   Display     *display = XtDisplay (w);
  936.  
  937.   XFreeGC (display, gw->goban.black_fg_gc  );
  938.   XFreeGC (display, gw->goban.black_bg_gc  );
  939.   XFreeGC (display, gw->goban.black_bd_gc  );
  940.   XFreeGC (display, gw->goban.white_fg_gc  );
  941.   XFreeGC (display, gw->goban.white_bg_gc  );
  942.   XFreeGC (display, gw->goban.white_bd_gc  );
  943.   XFreeGC (display, gw->goban.foreground_gc);
  944.   XFreeGC (display, gw->goban.background_gc);
  945.   XFreeGC (display, gw->goban.copy_gc      );
  946. }
  947.  
  948. /****************************************************************************************************************
  949.  */
  950.  
  951. static void Destroy (w)
  952. Widget w;
  953. {
  954.   GobanWidget  gw      = (GobanWidget) w;
  955.   Display     *display = XtDisplay (w);
  956.  
  957.   DestroyPixmap (w);
  958.   DestroyGC     (w);
  959.  
  960.   XFreePixmap (display, gw->goban.white_stone  );
  961.   XFreePixmap (display, gw->goban.black_stone  );
  962.   XFreePixmap (display, gw->goban.gray_stone   );
  963.   XFreePixmap (display, gw->goban.mouse_mask   );
  964.  
  965.   XFreeCursor (display, gw->goban.white_cursor );
  966.   XFreeCursor (display, gw->goban.black_cursor );
  967.   XFreeCursor (display, gw->goban.gray_cursor  );
  968.   XFreeCursor (display, gw->goban.font_cursor  );
  969. }
  970.  
  971. /****************************************************************************************************************
  972.  */
  973.  
  974. static void Realize (w, valuemaskp, attr)
  975. Widget                w;
  976. XtValueMask          *valuemaskp;
  977. XSetWindowAttributes *attr;
  978. {
  979.   GobanWidget  gw      = (GobanWidget) w;
  980.   
  981.   *valuemaskp |= CWCursor;
  982.  
  983.   switch (gw->goban.cursor) {
  984.   case GbCBlackStone : attr->cursor = gw->goban.black_cursor; break;
  985.   case GbCWhiteStone : attr->cursor = gw->goban.white_cursor; break;
  986.   default            : attr->cursor = gw->goban.font_cursor ; break;
  987.   }
  988.   
  989.   XtCreateWindow (w, InputOutput, (Visual *) CopyFromParent, *valuemaskp, attr);
  990. }
  991.  
  992. /****************************************************************************************************************
  993.  */
  994.  
  995. static char *stars[18] = {
  996.   "",                /*  2  */  
  997.   "",                /*  3  */  
  998.   "",                /*  4  */  
  999.   "",                /*  5  */  
  1000.   "",                /*  6  */  
  1001.   "",                /*  7  */  
  1002.   "cccffcff",            /*  8  */    
  1003.   "cccgeegcgg",            /*  9  */  
  1004.   "ccchhchh",            /* 10  */  
  1005.   "cccfcifcfffiicifii",        /* 11  */  
  1006.   "dddiidii",            /* 12  */  
  1007.   "dddjggjdjj",            /* 13  */  
  1008.   "dddkkdkk",            /* 14  */  
  1009.   "dddhdlhdhhhlldlhll",        /* 15  */  
  1010.   "dddmmdmm",            /* 16  */  
  1011.   "dddidnidiiinndninn",        /* 17  */  
  1012.   "dddoodoo",            /* 18  */  
  1013.   "dddjdpjdjjjppdpjpp",        /* 19  */  
  1014. };
  1015.  
  1016. static void DrawBoard (w)
  1017. Widget w;
  1018. {
  1019.   GobanWidget  gw         = (GobanWidget) w;
  1020.   Display     *display    = XtDisplay (w);
  1021.   XSegment     segment[44];
  1022.   int          segc;
  1023.   Position     game_size  = (Position) gw->goban.game_size;
  1024.   Position     point_size = (Position) gw->goban.point_size;
  1025.   Position     star_size  = 4;
  1026.   Position     xbase      = gw->goban.x_offset + point_size / 2;
  1027.   Position     ybase      = gw->goban.y_offset - point_size / 2;
  1028.   Position     xmin       = gw->goban.x_offset + point_size * gw->goban.left + 1;
  1029.   Position     ymin       = gw->goban.y_offset - point_size * gw->goban.top  + 1;
  1030.   Position     xmax       = gw->goban.x_offset + point_size * (gw->goban.right  + 1) - 1;
  1031.   Position     ymax       = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
  1032.   char        *star;
  1033.   int          x;
  1034.   int          y;
  1035.  
  1036.   XFillRectangle (display, gw->goban.board, gw->goban.background_gc, 0, 0, w->core.width, w->core.height);
  1037.  
  1038.   if (point_size > 0) {
  1039.     segc = 0;
  1040.     for (y = gw->goban.bottom - 1; y < gw->goban.top; y++, segc++) {
  1041.       segment[segc].x1 = (short) Max ((int) xbase + point_size , xmin);
  1042.       segment[segc].x2 = (short) Min ((int) xbase + point_size * game_size, xmax);
  1043.       segment[segc].y1 = (short) (ybase - point_size * y);
  1044.       segment[segc].y2 = (short) (ybase - point_size * y);
  1045.     }
  1046.     
  1047.     for (x = gw->goban.left; x <= gw->goban.right; x++, segc++) {
  1048.       segment[segc].x1 = (short) (xbase + point_size * x);
  1049.       segment[segc].x2 = (short) (xbase + point_size * x);
  1050.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1), ymin);
  1051.       segment[segc].y2 = (short) Min (ybase, ymax);
  1052.     }
  1053.     
  1054.     if (gw->goban.top == gw->goban.game_size) {
  1055.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  1056.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  1057.       segment[segc].y1 = (short) (ybase - point_size * (game_size - 1) - 1);
  1058.       segment[segc].y2 = (short) (ybase - point_size * (game_size - 1) - 1);
  1059.       segc++;
  1060.     }
  1061.     
  1062.     if (gw->goban.bottom == 1) {
  1063.       segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
  1064.       segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
  1065.       segment[segc].y1 = (short) (ybase + 1);
  1066.       segment[segc].y2 = (short) (ybase + 1);
  1067.       segc++;
  1068.     }
  1069.     
  1070.     if (gw->goban.left == 1) {
  1071.       segment[segc].x1 = (short) (xbase + point_size - 1);
  1072.       segment[segc].x2 = (short) (xbase + point_size - 1);
  1073.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin); 
  1074.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  1075.       segc++;
  1076.     }
  1077.     
  1078.     if (gw->goban.right == gw->goban.game_size) {
  1079.       segment[segc].x1 = (short) (xbase + point_size * game_size + 1);
  1080.       segment[segc].x2 = (short) (xbase + point_size * game_size + 1);
  1081.       segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin);
  1082.       segment[segc].y2 = (short) Min (ybase + 1, ymax);
  1083.       segc++;
  1084.     }
  1085.     
  1086.     XDrawSegments (display, gw->goban.board, gw->goban.foreground_gc, segment, segc);
  1087.     
  1088.     if (point_size > 8) {
  1089.       star_size = (point_size > 10) ? 4 : 2;
  1090.       star      = stars[game_size - 2];
  1091.       
  1092.       while (*star != '\0') {
  1093.     x = *star++ - 'a' + 1;
  1094.     y = *star++ - 'a' + 1;
  1095.     
  1096.     if (x >= gw->goban.left && x <= gw->goban.right && y >= gw->goban.bottom && y <= gw->goban.top) {
  1097.       x = gw->goban.x_offset + (point_size * (2 * x + 1)) / 2;
  1098.       y = gw->goban.y_offset - (point_size * (2 * y - 1)) / 2;
  1099.       
  1100.       XDrawArc (display, gw->goban.board, gw->goban.foreground_gc, 
  1101.             (int) x - star_size / 2, (int) y - star_size / 2, 
  1102.             (unsigned int) star_size, (unsigned int) star_size, 
  1103.             0, 64 * 360);
  1104.       XFillArc (display, gw->goban.board, gw->goban.foreground_gc, 
  1105.             (int) x - star_size / 2, (int) y - star_size / 2, 
  1106.             (unsigned int) star_size, (unsigned int) star_size, 
  1107.             0, 64 * 360);
  1108.     }
  1109.       }
  1110.     }
  1111.   }
  1112.  
  1113.   XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, 0, 0, 
  1114.          w->core.width, w->core.height, 0, 0);
  1115. }
  1116.  
  1117. /****************************************************************************************************************
  1118.  */
  1119.  
  1120. static void DrawCoordinates (w)
  1121. Widget w;
  1122. {
  1123.   GobanWidget  gw         = (GobanWidget) w;
  1124.   Display     *display    = XtDisplay (w);
  1125.   XCharStruct  extent;
  1126.   int          point_size = gw->goban.point_size;
  1127.   char         s[2];
  1128.   int          len;
  1129.   int          ascent;
  1130.   int          descent;
  1131.   int          direction;
  1132.   int          xbase;
  1133.   int          ybase;
  1134.   int          x;
  1135.   int          y;
  1136.   unsigned int width;
  1137.   unsigned int height;
  1138.  
  1139.   s[0] = s[1] = '8';
  1140.   XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1141.              s, 2, &direction, &ascent, &descent, &extent);
  1142.  
  1143.   if ((point_size > extent.width + 2) && (point_size > extent.ascent + extent.descent + 2)) {
  1144.     xbase = 2 * gw->goban.x_offset + point_size;
  1145.     ybase = 2 * gw->goban.y_offset - point_size;
  1146.  
  1147.     if (gw->goban.display_coordinates == TRUE) {
  1148.     
  1149.       for (x = gw->goban.left; x <= gw->goban.right; x++) {
  1150.     s[0] = 'A' - 1 + ((x > 8) ? (x + 1) : x);
  1151.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1152.                s, 1, &direction, &ascent, &descent, &extent);
  1153.  
  1154.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1155.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1156.              (ybase + extent.ascent - extent.descent) / 2 - point_size * gw->goban.top + 1, s, 1);
  1157.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1158.              (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1, 
  1159.              (ybase + extent.ascent - extent.descent) / 2 - point_size * (gw->goban.bottom - 2) + 1, s, 1);
  1160.       }
  1161.     }
  1162.  
  1163.     x      = gw->goban.x_offset + point_size * gw->goban.left;
  1164.     y      = gw->goban.y_offset - point_size * (gw->goban.top + 1);
  1165.     width  = point_size * (gw->goban.right - gw->goban.left + 1);
  1166.     height = point_size;
  1167.     
  1168.     if (gw->goban.display_coordinates == FALSE)
  1169.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1170.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1171.  
  1172.     y      = gw->goban.y_offset - point_size * (gw->goban.bottom - 1);
  1173.  
  1174.     if (gw->goban.display_coordinates == FALSE)
  1175.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1176.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1177.     
  1178.     ybase += 2 * point_size;
  1179.  
  1180.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1181.       if (gw->goban.display_coordinates == TRUE) {
  1182.     len = 0;
  1183.     if (y > 9)
  1184.       s[len++] = '1';
  1185.     s[len++] = '0' + y % 10;
  1186.     XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
  1187.                s, len, &direction, &ascent, &descent, &extent);
  1188.  
  1189.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1190.              (xbase - extent.width) / 2 + point_size * (gw->goban.left  - 1) - extent.lbearing + 1, 
  1191.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1192.     XDrawString (display, gw->goban.board, gw->goban.foreground_gc, 
  1193.              (xbase - extent.width) / 2 + point_size * (gw->goban.right + 1) - extent.lbearing + 1, 
  1194.              (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
  1195.       }
  1196.     }
  1197.  
  1198.     x      = gw->goban.x_offset + point_size * (gw->goban.left  - 1);
  1199.     y      = gw->goban.y_offset - point_size * gw->goban.top;
  1200.     width  = point_size;
  1201.     height = point_size * (gw->goban.top - gw->goban.bottom + 1);;
  1202.     
  1203.     if (gw->goban.display_coordinates == FALSE)
  1204.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1205.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1206.  
  1207.     x      = gw->goban.x_offset + point_size * (gw->goban.right + 1);
  1208.     
  1209.     if (gw->goban.display_coordinates == FALSE)
  1210.       XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
  1211.     XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
  1212.   }
  1213.  
  1214. }
  1215.  
  1216. /****************************************************************************************************************
  1217.  */
  1218.  
  1219. static void InitializeSize (w)
  1220. Widget w;
  1221. {  
  1222.   GobanWidget  gw        = (GobanWidget) w;
  1223.   Position     bottom    = Min (gw->goban.bottom, gw->goban.top  );
  1224.   Position     left      = Min (gw->goban.left  , gw->goban.right);
  1225.   Position     top       = Max (gw->goban.bottom, gw->goban.top  );
  1226.   Position     right     = Max (gw->goban.left  , gw->goban.right);
  1227.   Dimension    game_size = gw->goban.game_size;
  1228.   Dimension    width;
  1229.   Dimension    height;
  1230.  
  1231.   game_size = (game_size > 1      && game_size <  20       ) ? game_size : 19;
  1232.   bottom    = (bottom    > 0      && bottom    <  (Position)game_size) ? bottom    : 1;
  1233.   left      = (left      > 0      && left      <  (Position)game_size) ? left      : 1;
  1234.   top       = (top       > bottom && top       <= (Position)game_size) ? top       : game_size;
  1235.   right     = (right     > left   && right     <= (Position)game_size) ? right     : game_size;
  1236.  
  1237.   width     = right - left   + 3;
  1238.   height    = top   - bottom + 3;
  1239.  
  1240.   if ((w->core.height == 0) && (w->core.width == 0)) {
  1241.     w->core.width  = gw->goban.point_size * width ;
  1242.     w->core.height = gw->goban.point_size * height;
  1243.   } 
  1244.  
  1245.   else 
  1246.     gw->goban.point_size = Min ((int)w->core.width / (int)width, (int)w->core.height / (int)height);
  1247.  
  1248.   gw->goban.game_size = game_size;
  1249.   gw->goban.bottom    = bottom;
  1250.   gw->goban.left      = left;
  1251.   gw->goban.top       = top;
  1252.   gw->goban.right     = right;
  1253.   gw->goban.x_offset  = (int) (w->core.width  - gw->goban.point_size * (width  + 2 * left - 2)) / 2;
  1254.   gw->goban.y_offset  = (int) (w->core.height - gw->goban.point_size * (height - 2 * top  - 2)) / 2;
  1255. }
  1256.  
  1257. /****************************************************************************************************************
  1258.  */
  1259.  
  1260. /* ARGSUSED */
  1261.  
  1262. static void Initialize (request, new)
  1263. Widget request;
  1264. Widget new;
  1265. {
  1266.     GobanWidget   gw      = (GobanWidget) new;
  1267.     gw->goban.left = 1;
  1268.     gw->goban.right = 19;
  1269.     gw->goban.top = 1;
  1270.     gw->goban.bottom = 19;
  1271.  
  1272.   InitializeSize   (new);
  1273.   InitializePixmap (new);
  1274.   InitializeGC     (new);
  1275.   InitializeCursor (new);
  1276.   DrawBoard        (new);
  1277.   DrawCoordinates  (new);
  1278.   GbClearBoard     (new);
  1279. }
  1280.  
  1281. /****************************************************************************************************************
  1282.  */
  1283.  
  1284. static void DrawPoint (w, x, y, color, flag)
  1285. Widget      w;
  1286. int         x;
  1287. int         y;
  1288. GbPointState color;
  1289. Boolean flag;    /*SC  TRUE to mark as "Last"  FALSE to just draw stone */
  1290. {
  1291.   GobanWidget   gw      = (GobanWidget) w;
  1292.   Display      *display = XtDisplay (w);
  1293.   unsigned int  size    = (unsigned int) gw->goban.point_size - 2;
  1294.   XExposeEvent  event;
  1295.   int           X, XX;
  1296.   int           Y, YY;
  1297.  
  1298.   if (size > 1) {
  1299.     X = gw->goban.x_offset + gw->goban.point_size * x + 1;
  1300.     Y = gw->goban.y_offset - gw->goban.point_size * y + 1;
  1301.     XX = X + size/4 +1;
  1302.     YY = Y + size/4 +1;
  1303.  
  1304.     
  1305.     switch (color)
  1306.       {
  1307.       case GbBlackStone :
  1308.     XFillArc (display, gw->goban.picture, gw->goban.black_bg_gc, X, Y,
  1309.             size, size, 0, 360 * 64);
  1310.     XDrawArc (display, gw->goban.picture, gw->goban.black_bd_gc, X, Y,
  1311.             size, size, 0, 360 * 64);
  1312.     if( flag ) {
  1313.        XFillArc( display, gw->goban.picture, gw->goban.black_fg_gc,
  1314.              XX, YY, size/2, size/2, 0, 360*64 );
  1315.        lastx = X;
  1316.        lasty = Y;
  1317.            lastcolor = color;
  1318.        }
  1319.  
  1320.     else XDrawArc (display, gw->goban.picture, gw->goban.black_fg_gc,
  1321.             X + (int) size / 6, Y + (int) size / 6, 
  1322.               (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1323.     break;
  1324.       case GbWhiteStone :
  1325.     XFillArc (display, gw->goban.picture, gw->goban.white_bg_gc, X, Y,
  1326.             size, size, 0, 360 * 64);
  1327.     XDrawArc (display, gw->goban.picture, gw->goban.white_bd_gc, X, Y,
  1328.             size, size, 0, 360 * 64);
  1329.     if( flag ) {
  1330.         XFillArc( display, gw->goban.picture, gw->goban.white_fg_gc,
  1331.             XX, YY, size/2, size/2, 0, 360*64 );
  1332.         lastx = X;
  1333.         lasty = Y;
  1334.         lastcolor = color;
  1335.     }
  1336.     else XDrawArc (display, gw->goban.picture, gw->goban.white_fg_gc,
  1337.             X + (int) size / 6, Y + (int) size / 6, 
  1338.               (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
  1339.     break;
  1340.       case GbEmptyPoint :
  1341.     XCopyArea (XtDisplay (w), gw->goban.board, gw->goban.picture,
  1342.             gw->goban.copy_gc, X, Y, gw->goban.point_size,
  1343.             gw->goban.point_size, X, Y); 
  1344.     break;
  1345.       }
  1346.     
  1347.     if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
  1348.       event.x      = X - 1;
  1349.       event.y      = Y - 1;
  1350.       event.width  = gw->goban.point_size;
  1351.       event.height = gw->goban.point_size;
  1352.  
  1353.       Redisplay (w, &event, (Region) NULL);
  1354.     }
  1355.   }
  1356. }
  1357.  
  1358. /****************************************************************************************************************
  1359.  */
  1360.  
  1361. static void RedrawStones (w)
  1362. Widget w;
  1363. {
  1364.   GobanWidget  gw         = (GobanWidget) w;
  1365.   Boolean      redisplay  = gw->goban.auto_redisplay;
  1366.   Position     x;
  1367.   Position     y;
  1368.  
  1369.   gw->goban.auto_redisplay = FALSE;
  1370.  
  1371.   for (x = gw->goban.left; x <= gw->goban.right; x++)
  1372.     for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
  1373.       if (gw->goban.points[x][y].free == 0) {
  1374.     if (gw->goban.points[x][y].black == 1) {
  1375.       DrawPoint (w, x, y, GbBlackStone, FALSE);
  1376.     }
  1377.     else {
  1378.       DrawPoint (w, x, y, GbWhiteStone, FALSE);
  1379.     }
  1380.     if (gw->goban.points[x][y].num > 0)
  1381.       GbSetNum (w, x, y, (int) gw->goban.points[x][y].num);
  1382.       }
  1383.  
  1384.       if (gw->goban.points[x][y].mark1 != 0 || gw->goban.points[x][y].mark2 != 0)
  1385.     GbSetMark (w, x, y, gw->goban.points[x][y].mark1, gw->goban.points[x][y].mark2);
  1386.     }
  1387.  
  1388.   gw->goban.auto_redisplay = redisplay;
  1389.  
  1390.   if (redisplay == TRUE) GbRedisplayBoard (w);
  1391. }
  1392.  
  1393. /****************************************************************************************************************
  1394.  */
  1395.  
  1396. static void Resize (w)
  1397. Widget w;
  1398. {
  1399.   DestroyPixmap    (w);
  1400.   DestroyGC        (w);
  1401.   InitializeSize   (w);
  1402.   InitializePixmap (w);
  1403.   InitializeGC     (w);
  1404.   DrawBoard        (w);
  1405.   DrawCoordinates  (w);
  1406.   RedrawStones     (w);
  1407. }
  1408.  
  1409. /****************************************************************************************************************
  1410.  */
  1411.  
  1412. /* ARGSUSED */
  1413.  
  1414. static Boolean SetValues (current, request, new)
  1415. Widget current;
  1416. Widget request;
  1417. Widget new;
  1418. {
  1419.   GobanWidget gnew      = (GobanWidget) new;
  1420.   GobanWidget gcurrent  = (GobanWidget) current;
  1421.   Boolean     redisplay = FALSE;
  1422.  
  1423.   if (gnew->goban.point_size != gcurrent->goban.point_size)
  1424.     gnew->goban.point_size = gcurrent->goban.point_size;
  1425.  
  1426.   if (XtIsRealized (new)) {
  1427.     if (gnew->goban.cursor != gcurrent->goban.cursor) {
  1428.  
  1429.       switch (gnew->goban.cursor) {
  1430.  
  1431.       case GbCBlackStone : 
  1432.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.black_cursor);
  1433.     break;
  1434.       case GbCWhiteStone : 
  1435.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.white_cursor);
  1436.     break;
  1437.       default :
  1438.     XFreeCursor (XtDisplay (new), gnew->goban.font_cursor );
  1439.     gnew->goban.font_cursor = XCreateFontCursor (XtDisplay (new), (unsigned int) gnew->goban.cursor);
  1440.     XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.font_cursor);
  1441.       }
  1442.     }
  1443.   }
  1444.  
  1445.   if (gnew->goban.game_size != gcurrent->goban.game_size) 
  1446.     if (gnew->goban.game_size > 1 && gnew->goban.game_size < 20) {
  1447.  
  1448.       gnew->goban.bottom = 1;
  1449.       gnew->goban.left   = 1;
  1450.       gnew->goban.top    = gnew->goban.game_size;
  1451.       gnew->goban.right  = gnew->goban.game_size;
  1452.       
  1453.       InitializeSize   (new);
  1454.       DrawBoard        (new);
  1455.       DrawCoordinates  (new);
  1456.       GbClearBoard     (new);
  1457.       
  1458.       redisplay = TRUE;
  1459.     }
  1460.     else
  1461.       gnew->goban.game_size = gcurrent->goban.game_size;
  1462.  
  1463.   else if (gnew->goban.top    != gcurrent->goban.top   ||
  1464.        gnew->goban.left   != gcurrent->goban.left  ||
  1465.        gnew->goban.right  != gcurrent->goban.right ||
  1466.        gnew->goban.bottom != gcurrent->goban.bottom) {
  1467.  
  1468.     InitializeSize  (new);
  1469.     DrawBoard       (new);
  1470.     DrawCoordinates (new);
  1471.     RedrawStones    (new);
  1472.  
  1473.     redisplay = TRUE;
  1474.   }
  1475.  
  1476.   else if (new->core.background_pixel != current->core.background_pixel || 
  1477.            gnew->goban.foreground     != gcurrent->goban.foreground     ||
  1478.            gnew->goban.white_fg       != gcurrent->goban.white_fg       ||
  1479.            gnew->goban.white_bg       != gcurrent->goban.white_bg       ||
  1480.            gnew->goban.white_bd       != gcurrent->goban.white_bd       ||
  1481.            gnew->goban.black_fg       != gcurrent->goban.black_fg       ||
  1482.            gnew->goban.black_bg       != gcurrent->goban.black_bg       ||
  1483.            gnew->goban.black_bd       != gcurrent->goban.black_bd       ) {
  1484.  
  1485.     DestroyGC        (new);
  1486.     InitializeGC     (new);
  1487.     DrawBoard        (new);
  1488.     DrawCoordinates  (new);
  1489.     RedrawStones     (new);
  1490.  
  1491.     redisplay = TRUE;
  1492.   }
  1493.  
  1494.   if (gnew->goban.display_coordinates != gcurrent->goban.display_coordinates) {
  1495.     DrawCoordinates (new);
  1496.  
  1497.     redisplay = TRUE;
  1498.   }
  1499.  
  1500.   return (gnew->goban.auto_redisplay == True) ? redisplay : False;
  1501. }
  1502.  
  1503. /****************************************************************************************************************
  1504.  */
  1505. SHAR_EOF
  1506. fi
  1507. if test -f 'Goban.doc'
  1508. then
  1509.     echo shar: "will not over-write existing file 'Goban.doc'"
  1510. else
  1511. cat << \SHAR_EOF > 'Goban.doc'
  1512. Goban Widget 
  1513. ------------
  1514.  
  1515.  The Goban widget displays a full or partial go board within a rectangular area and 
  1516.  allows an application to put or remove stones on it. The application can also draw 
  1517.  numbers on stones, and marks (consisting of a one or two characters string) on stones 
  1518.  or empty points. It has no knowledge of the game and thus doesn't remove dead stones 
  1519.  if any (it is the application's responsability).
  1520.  
  1521.  For every position specification, the coordinate system uses an x axis going from left
  1522.  to right, and an y axis going from bottom to top.
  1523.  
  1524. Resources
  1525. ---------
  1526.  
  1527.  Name               Class          RepType        Default Value
  1528.  ----               -----          -------        -------------
  1529.  autoRedisplay         AutoRedisplay      Boolean         True
  1530.  background           Background      Pixel          XtDefaultBackground
  1531.  blackStoneBackground  Background      Pixel          black
  1532.  blackStoneBorder      BorderColor      Pixel          black
  1533.  blackStoneForeground  Foreground      Pixel          white
  1534.  border               BorderColor      Pixel          XtDefaultForeground
  1535.  borderWidth           BorderWidth      Dimension      1
  1536.  cursor                Cursor             Integer         GbGrayCursor
  1537.  destroyCallback       Callback          Pointer      NULL
  1538.  displayCoordinates    DisplayCoordinates Boolean      True
  1539.  font                  Font               XFontStruct*    fixed
  1540.  foreground            Foreground         Pixel           XtDefaultForeground
  1541.  gameSize              Size               Dimension       19
  1542.  height               Height          Dimension      computed at create
  1543.  mappedWhenManaged     MappedWhenManaged  Boolean      True
  1544.  pointSize             Size               Dimension       24
  1545.  sensitive           Sensitive      Boolean      True
  1546.  viewBottom            Position           Position        computed at create
  1547.  viewLeft              Position           Position        computed at create
  1548.  viewRight             Position           Position        computed at create
  1549.  viewTop               Position           Position        computed at create
  1550.  whiteStoneBackground  Background      Pixel          white
  1551.  whiteStoneBorder      BorderColor      Pixel          black
  1552.  whiteStoneForeground  Foreground      Pixel          black
  1553.  width               Width          Dimension      computed at create
  1554.  x               Position          Position      0
  1555.  y               Position          Position      0
  1556.  
  1557.  autoRedisplay          If this resource is True, then all changes on the widget (put or remove
  1558.               stones, put numbers or marks) will be immediatly flushed to the screen.
  1559.               This can be set to False in conjonction with GbRedisplay in order to 
  1560.               improve the speed when displaying a position.
  1561.  
  1562.  background          As usual.
  1563.  backgroundPixmap     As usual.
  1564.  
  1565.  blackStoneBackground This color will be used to fill the black stones (usually black)
  1566.  blackStoneBorder     This color will be used to draw a circle arround the black stones. This is
  1567.                       usefull with white stones to delimit the circumference of the stone.
  1568.  blackStoneForeground This color will be used to draw marks and numbers on black stones.
  1569.  
  1570.  border              As usual.
  1571.  borderWidth          As usual.
  1572.  
  1573.  
  1574.  cursor              The cursor that will be displayed : should be GbCGrayStone, GbCWhiteStone
  1575.               or GbCBlackStone or a valid cursorFont ID.
  1576.  
  1577.  destroyCallback      As usual.
  1578.  
  1579.  font              The font that will be used to put numbers and marks on the board and to
  1580.               display the coordinate marks.
  1581.  
  1582.  foreground          As usual.
  1583.  
  1584.  gameSize          The board size : board is always square and its size must range between
  1585.               2 and 19.
  1586.  
  1587.  height              As usual.
  1588.  
  1589.  mappedWhenManaged    As usual.
  1590.  
  1591.  displayCoordinates   If this resource is True, then the coordinate marks will be displayed 
  1592.               around the board.
  1593.  
  1594.  pointSize          The distance in pixels between points.
  1595.      
  1596.  sensitive          As usual.
  1597.  
  1598.  viewBottom           The bottom of the partial goban that is viewed. Must range between 1 and
  1599.               gameSize - 1.
  1600.  
  1601.  viewLeft          The left of the partial goban that is viewed. Must range between 1 and
  1602.               gameSize - 1.
  1603.  
  1604.  viewRight          The right of the partial goban that is viewed. Must range between 
  1605.               viewLeft + 1 and gameSize.
  1606.  
  1607.  viewTop          The top of the partial goban that is viewed. Must range between
  1608.               viewBottom + 1 and gameSize.
  1609.  
  1610.  width              As usual.
  1611.  
  1612.  whiteStoneBackground This color will be used to fill the white stones (usually white)
  1613.  whiteStoneBorder     This color will be used to draw a circle arround the white stones.
  1614.  whiteStoneForeground This color will be used to draw marks and numbers on white stones.
  1615.  
  1616.  x              As usual.
  1617.  y              As usual.
  1618.  
  1619.  
  1620. Procedures provided for application
  1621. -----------------------------------  
  1622.  
  1623. void GbRedisplayBoard (w)
  1624. GobanWidget w;
  1625.  
  1626.  Redisplay the entire board <w> on the screen.
  1627.  
  1628. void GbClearBoard (w)
  1629. GobanWidget w;
  1630.  
  1631.  Remove all stones of the board <w> and call GbRedisplayBoard.
  1632.  
  1633.  
  1634. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone, } GbPointState;
  1635.  
  1636. void GbSetPoint (w, x, y, color)     
  1637. GobanWidget  w;
  1638. Position     x;
  1639. Position     y; 
  1640. GbPointState color;
  1641.  
  1642.  Put a stone of color <color> at location <x><y> on the board <w>.
  1643.  If color is GbEmptyPoint, then the stone (if any) is removed from location <x><y>.
  1644.  All marks on this point are removed.
  1645.  If autoRedisplay if set to False the change will not be visible on the screen until
  1646.  the application calls GbRedisplay.
  1647.  
  1648.  
  1649. void GbSetNum (w, x, y, num)
  1650. GobanWidget  w;
  1651. Position     x;
  1652. Position     y;
  1653. unsigned int num;
  1654.  
  1655.  Draw the number <num> on the stone at location <x><y> on the board <w>.
  1656.  <num> must range between 0 and 999 and no number is displayed if there is no stone
  1657.  at this location.
  1658.  If <num> is equal to 0, all previous num (if any) is removed from stone.
  1659.  When the representation of <num> is to bigger than the stone size (according to font size) 
  1660.  no number is displayed.
  1661.  
  1662.  
  1663. void GbSetMark (w, x, y, mark1, mark2)
  1664. GobanWidget   w;
  1665. Position      x;
  1666. Position      y;
  1667. unsigned char mark1;
  1668. unsigned char mark2;
  1669.  
  1670.  Draw the two characters mark at location <x><y> on the board <w>.
  1671.  <x><y> may be an empty point.
  1672.  If <mark1> and <mark2> are equal to 0, the previous mark (if any) is removed from point.
  1673.  If <mark2> is equal to 0, only one character will be displayed.
  1674.  If <mark1> is equal to 0, <mark2> can be one of GbMSquareMark, GbMTriangleMark, GbMVCrossMark, 
  1675.  GbMDCrossMark or GbMDiamondMark. In this case, geometric marks are drawn.
  1676.  When the representation of the mark is to bigger than the stone size (according to font size) 
  1677.  no mark is displayed.
  1678.  GbRemoveMark(w,x,y) is defined as a macro call for GbSetMark(w,x,y,0,0).
  1679.  
  1680.  
  1681. Boolean GbGetStoneFromPosition (w, x, y)
  1682. GobanWidget   w;
  1683. Position     *x;
  1684. Position     *y;
  1685.  
  1686.  Provide a way to know on what point occurs a mouse event.
  1687.  If the event occurs on a valid point on the board, GbGetStoneFromEvent returns TRUE,
  1688.  and <x> <y> variables are set to the coordinates of that point.
  1689.  If not, GbGetStoneFromEvent returns FALSE and <event> is unchanged.
  1690.  
  1691.  
  1692. Boolean GbGetPositionFromStone (w, x, y)
  1693. GobanWidget   w;
  1694. Position     *x;
  1695. Position     *y;
  1696.  
  1697.  Provide a way to know what are the coordinates (in pixel) for the center of a given 
  1698.  point. It works as GbGetStoneFromPosition.
  1699.  Those functions are not reverse of each other ...
  1700.  
  1701. SHAR_EOF
  1702. fi
  1703. if test -f 'Goban.h'
  1704. then
  1705.     echo shar: "will not over-write existing file 'Goban.h'"
  1706. else
  1707. cat << \SHAR_EOF > 'Goban.h'
  1708. /****************************************************************************************************************
  1709.  *
  1710.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1711.  *
  1712.  *  This program is distributed in the hope that it will be useful.
  1713.  *  Use and copying of this software and preparation of derivative works
  1714.  *  based upon this software are permitted, so long as the following
  1715.  *  conditions are met:
  1716.  *       o credit to the authors is acknowledged following current
  1717.  *         academic behaviour
  1718.  *       o no fees or compensation are charged for use, copies, or
  1719.  *         access to this software
  1720.  *       o this copyright notice is included intact.
  1721.  *  This software is made available AS IS, and no warranty is made about 
  1722.  *  the software or its performance. 
  1723.  * 
  1724.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1725.  *  Send them to    dumesnil@etca.fr   or to:
  1726.  *       
  1727.  *       Antoine de Maricourt
  1728.  *       ETCA CREA-SP
  1729.  *       16 bis, avenue Prieur de la Cote d'Or
  1730.  *       94114 Arcueil Cedex
  1731.  *       France
  1732.  */
  1733.  
  1734. #ifndef _Goban_h
  1735. #define _Goban_h
  1736.  
  1737. /* Resources:
  1738.  
  1739.  Name               Class          RepType        Default Value
  1740.  ----               -----          -------        -------------
  1741.  autoRedisplay         AutoRedisplay      Boolean         True
  1742.  background           Background      Pixel          XtDefaultBackground
  1743.  blackStoneBackground  Background      Pixel          black
  1744.  blackStoneBorder      BorderColor      Pixel          black
  1745.  blackStoneForeground  Foreground      Pixel          white
  1746.  border               BorderColor      Pixel          XtDefaultForeground
  1747.  borderWidth           BorderWidth      Dimension      1
  1748.  cursor                Cursor             Integer         GbGrayCursor
  1749.  destroyCallback       Callback          Pointer      NULL
  1750.  displayCoordinates    DisplayCoordinates Boolean      True
  1751.  font                  Font               XFontStruct*    fixed
  1752.  foreground            Foreground         Pixel           XtDefaultForeground
  1753.  gameSize              Size               Dimension       19
  1754.  height               Height          Dimension      computed at create
  1755.  mappedWhenManaged     MappedWhenManaged  Boolean      True
  1756.  pointSize             Size               Dimension       24
  1757.  sensitive           Sensitive      Boolean      True
  1758.  viewBottom            Position           Position        computed at create
  1759.  viewLeft              Position           Position        computed at create
  1760.  viewRight             Position           Position        computed at create
  1761.  viewTop               Position           Position        computed at create
  1762.  whiteStoneBackground  Background      Pixel          white
  1763.  whiteStoneBorder      BorderColor      Pixel          black
  1764.  whiteStoneForeground  Foreground      Pixel          black
  1765.  width               Width          Dimension      computed at create
  1766.  x               Position          Position      0
  1767.  y               Position          Position      0
  1768. */
  1769.  
  1770. /* define any special resource names here that are not in <X11/StringDefs.h> */
  1771.  
  1772. #define XtNautoRedisplay         "autoRedisplay"
  1773. #define XtNviewBottom            "viewBottom"
  1774.  
  1775. #ifndef XtNcursor
  1776. #define XtNcursor                "cursor"
  1777. #endif
  1778.  
  1779. #define XtNgameSize              "gameSize"
  1780. #define XtNviewLeft              "viewLeft"
  1781. #define XtNdisplayCoordinates    "displayCoordinates"
  1782. #define XtNpointSize             "pointSize"
  1783. #define XtNstipple               "stipple"
  1784. #define XtNviewRight             "viewRight"
  1785. #define XtNviewTop               "viewTop"
  1786. #define XtNblackStoneBorder      "blackStoneBorder"
  1787. #define XtNblackStoneForeground  "blackStoneForeground"
  1788. #define XtNblackStoneBackground  "blackStoneBackground"
  1789. #define XtNwhiteStoneBorder      "whiteStoneBorder"
  1790. #define XtNwhiteStoneForeground  "whiteStoneForeground"
  1791. #define XtNwhiteStoneBackground  "whiteStoneBackground"
  1792.  
  1793. #define XtCAutoRedisplay         "AutoRedisplay"
  1794. #define XtCDisplayCoordinates    "DisplayCoordinates"
  1795. #define XtCSize                  "Size"
  1796. #define XtCStipple               "Stipple"
  1797.  
  1798. #define XtEgbWhiteStone          "white"
  1799. #define XtEgbBlackStone          "black"
  1800. #define XtEgbGrayStone           "gray"
  1801.  
  1802. /* declare specific GobanWidget class and instance datatypes */
  1803.  
  1804. typedef struct _GobanClassRec*     GobanWidgetClass;
  1805. typedef struct _GobanRec*     GobanWidget;
  1806.  
  1807. /* declare the class constant */
  1808.  
  1809. extern WidgetClass gobanWidgetClass;
  1810.  
  1811. /* cursors */
  1812.  
  1813. #define GbCGrayStone         256
  1814. #define GbCBlackStone        257
  1815. #define GbCWhiteStone        258
  1816.  
  1817. /* special marks */
  1818.  
  1819. #define GbMSquareMark        1
  1820. #define GbMTriangleMark      2
  1821. #define GbMVCrossMark        3
  1822. #define GbMDCrossMark        4
  1823. #define GbMDiamondMark       5
  1824.  
  1825. /* colors */
  1826.  
  1827. typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone } GbPointState;
  1828.  
  1829. /* user functions */
  1830.  
  1831. #define GbRemoveMark(w,x,y)  GbSetMark (w, x, y, 0, 0)
  1832.  
  1833. extern void GbRedisplayBoard ( /* Widget w */ );
  1834. extern void GbClearBoard     ( /* Widget w */ );
  1835. extern void GbSetPoint       ( /* Widget w, Position x, Position y, GbPointState color */ );
  1836. extern void GbSetNum         ( /* Widget w, Position x, Position y, int num   */ );
  1837. extern void GbSetMark        ( /* Widget w, Position x, Position y, unsigned char mark1, unsigned char mark2 */ );
  1838.  
  1839. extern Boolean GbGetPositionFromStone ( /* Widget w, Position *x, Position *y */ );
  1840. extern Boolean GbGetStoneFromPosition ( /* Widget w, Position *x, Position *y */ );
  1841.  
  1842. #endif /* _Goban_h */
  1843.  
  1844. SHAR_EOF
  1845. fi
  1846. if test -f 'GobanP.h'
  1847. then
  1848.     echo shar: "will not over-write existing file 'GobanP.h'"
  1849. else
  1850. cat << \SHAR_EOF > 'GobanP.h'
  1851. /****************************************************************************************************************
  1852.  *
  1853.  *  Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
  1854.  *
  1855.  *  This program is distributed in the hope that it will be useful.
  1856.  *  Use and copying of this software and preparation of derivative works
  1857.  *  based upon this software are permitted, so long as the following
  1858.  *  conditions are met:
  1859.  *       o credit to the authors is acknowledged following current
  1860.  *         academic behaviour
  1861.  *       o no fees or compensation are charged for use, copies, or
  1862.  *         access to this software
  1863.  *       o this copyright notice is included intact.
  1864.  *  This software is made available AS IS, and no warranty is made about 
  1865.  *  the software or its performance. 
  1866.  * 
  1867.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1868.  *  Send them to    dumesnil@etca.fr   or to:
  1869.  *       
  1870.  *       Antoine de Maricourt
  1871.  *       ETCA CREA-SP
  1872.  *       16 bis, avenue Prieur de la Cote d'Or
  1873.  *       94114 Arcueil Cedex
  1874.  *       France
  1875.  */
  1876.  
  1877. #ifndef _GobanP_h
  1878. #define _GobanP_h
  1879.  
  1880. #include "Goban.h"
  1881.  
  1882. /* include superclass private header file */
  1883. #include <X11/CoreP.h>
  1884.  
  1885. /* define unique representation types not found in <X11/StringDefs.h> */
  1886.  
  1887. #define XtRGobanResource "GobanResource"
  1888.  
  1889. typedef struct {
  1890.     int empty;
  1891. } GobanClassPart;
  1892.  
  1893. typedef struct _GobanClassRec {
  1894.     CoreClassPart    core_class;
  1895.     GobanClassPart    goban_class;
  1896. } GobanClassRec;
  1897.  
  1898. extern GobanClassRec gobanClassRec;
  1899.  
  1900. typedef struct {
  1901.   unsigned int free  : 1;
  1902.   unsigned int black : 1;
  1903.   unsigned int mark1 : 8;
  1904.   unsigned int mark2 : 8;
  1905.   unsigned int num   : 10;
  1906. } PointState;
  1907.  
  1908. typedef struct {
  1909.     /* resources */
  1910.  
  1911.   Boolean       auto_redisplay;
  1912.   Position      bottom;
  1913.   int           cursor;
  1914.   XFontStruct  *font;
  1915.   Pixel         foreground;
  1916.   Dimension     game_size;
  1917.   Position      left;
  1918.   Boolean       display_coordinates;
  1919.   Dimension     point_size;
  1920.   Boolean       stipple;
  1921.   Position      right;
  1922.   Position      top;
  1923.  
  1924.     /* private state */
  1925.  
  1926.   PointState    points[20][20];
  1927.   Position      x_offset;
  1928.   Position      y_offset;
  1929.  
  1930.   Pixmap        black_stone;
  1931.   Pixmap        board;
  1932.   Pixmap        gray_stone;
  1933.   Pixmap        mouse_mask;
  1934.   Pixmap        picture;
  1935.   Pixmap        white_stone;
  1936.  
  1937.   GC            background_gc;
  1938.   GC            foreground_gc;
  1939.   GC            black_fg_gc;
  1940.   GC            black_bg_gc;
  1941.   GC            black_bd_gc;
  1942.   GC            white_fg_gc;
  1943.   GC            white_bg_gc;
  1944.   GC            white_bd_gc;
  1945.   GC            copy_gc;
  1946.  
  1947.   Cursor        black_cursor;
  1948.   Cursor        gray_cursor;
  1949.   Cursor        white_cursor;
  1950.   Cursor        font_cursor;
  1951.  
  1952.   Pixel         white_bg;
  1953.   Pixel         white_fg;
  1954.   Pixel         white_bd;
  1955.   Pixel         black_bg;
  1956.   Pixel         black_fg;
  1957.   Pixel         black_bd;
  1958. } GobanPart;
  1959.  
  1960. typedef struct _GobanRec {
  1961.     CorePart    core;
  1962.     GobanPart    goban;
  1963. } GobanRec;
  1964.  
  1965. #define Min(x,y)      ((x) > (y) ? (y) : (x))
  1966. #define Max(x,y)      ((x) > (y) ? (x) : (y))
  1967.  
  1968. #endif /* _GobanP_h */
  1969. SHAR_EOF
  1970. fi
  1971. if test -f 'Imakefile'
  1972. then
  1973.     echo shar: "will not over-write existing file 'Imakefile'"
  1974. else
  1975. cat << \SHAR_EOF > 'Imakefile'
  1976. /* Imakefile for xigc v2.1
  1977.  * S.Coffin    USWAT   1/93
  1978.  */
  1979.  
  1980. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  1981.  *
  1982.  *  This program is distributed in the hope that it will be useful.
  1983.  *  Use and copying of this software and preparation of derivative works
  1984.  *  based upon this software are permitted, so long as the following
  1985.  *  conditions are met:
  1986.  *       o credit to the authors is acknowledged following current
  1987.  *         academic behaviour
  1988.  *       o no fees or compensation are charged for use, copies, or
  1989.  *         access to this software
  1990.  *       o this copyright notice is included intact.
  1991.  *  This software is made available AS IS, and no warranty is made about 
  1992.  *  the software or its performance. 
  1993.  * 
  1994.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  1995.  *  Send them to    scoffin@uswest.com
  1996.  */
  1997.  
  1998. LOCAL_LIBRARIES = XawClientLibs
  1999. SRCS1= Goban.c xigc.c filter.c pipes.c board.c
  2000. OBJS1= Goban.o xigc.o filter.o pipes.o board.o
  2001.  
  2002. SRCS2= igscomm.c
  2003. OBJS2= igscomm.o
  2004.  
  2005. PROGRAMS = xigc igscomm
  2006.  
  2007. ComplexProgramTarget_1 (xigc, $(LOCAL_LIBRARIES), )
  2008. ComplexProgramTarget_2 (igscomm,, )
  2009. InstallAppDefaults(XIgc)
  2010. InstallManPage(xigc,$(MANDIR))
  2011. SHAR_EOF
  2012. fi
  2013. if test -f 'Makefile.hand'
  2014. then
  2015.     echo shar: "will not over-write existing file 'Makefile.hand'"
  2016. else
  2017. cat << \SHAR_EOF > 'Makefile.hand'
  2018. # Makefile.hand
  2019. # S.Coffin  USWAT  12/92
  2020. #
  2021. # this is a hand-created makefile for xigc v2.1
  2022. # if your machine does not have "imake" or "xmkmf"
  2023. # you may be able to hack this up to adapt it to your system
  2024. # good luck
  2025.  
  2026. CFLAGS= -O -I/usr/include/X11
  2027. XLIBS= -L/usr/lib -lXaw -lXmu -lXt -lXext -lX11 -lm
  2028.  
  2029. SRCS1= Goban.c xigc.c filter.c pipes.c board.c
  2030. OBJS1= Goban.o xigc.o filter.o pipes.o board.o
  2031. HEAD1= filter.h Goban.h GobanP.h patchlevel.h shared.h
  2032.  
  2033. SRCS2= igscomm.c
  2034. OBJS2= igscomm.o
  2035. HEAD2= igscomm.h
  2036.  
  2037. all: xigc igscomm
  2038.  
  2039. xigc:    $(OBJS1)
  2040.     cc -o xigc $(OBJS1) $(XLIBS)
  2041.  
  2042. igscomm:    $(OBJS2)
  2043.     cc -o igscomm $(OBJS2)
  2044.  
  2045. clean:
  2046.     rm -f $(OBJS1) $(OBJS2) core xigc igscomm
  2047.  
  2048. $(OBJS1):    $(HEAD1)
  2049.  
  2050. $(OBJS2):    $(HEAD2)
  2051. SHAR_EOF
  2052. fi
  2053. if test -f 'Makefile.sun'
  2054. then
  2055.     echo shar: "will not over-write existing file 'Makefile.sun'"
  2056. else
  2057. cat << \SHAR_EOF > 'Makefile.sun'
  2058. # This is a sample Makefile for xigc v2.1, generated by "xmkmf"
  2059. # for the Sun SparcStation, SunOS 4.1.2, X11R5 pl 18
  2060. # You will probably not be able to use this without modification =SC 1/93
  2061.  
  2062. # Makefile generated by imake - do not edit!
  2063. # $XConsortium: imake.c,v 1.72 92/09/14 11:44:22 rws Exp $
  2064. #
  2065. # The cpp used on this machine replaces all newlines and multiple tabs and
  2066. # spaces in a macro expansion with a single space.  Imake tries to compensate
  2067. # for this, but is not always successful.
  2068. #
  2069.  
  2070. # -------------------------------------------------------------------------
  2071. # Makefile generated from "Imake.tmpl" and <Imakefile>
  2072. # $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
  2073. #
  2074. # Platform-specific parameters may be set in the appropriate <vendor>.cf
  2075. # configuration files.  Site-specific parameters should be set in the file
  2076. # site.def.  Full rebuilds are recommended if any parameters are changed.
  2077. #
  2078. # If your C preprocessor does not define any unique symbols, you will need
  2079. # to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
  2080. # "make World" the first time).
  2081. #
  2082.  
  2083. # -------------------------------------------------------------------------
  2084. # site-specific configuration parameters that need to come before
  2085. # the platform-specific parameters - edit site.def to change
  2086.  
  2087. # site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
  2088.  
  2089. # -------------------------------------------------------------------------
  2090. # platform-specific configuration parameters - edit sun.cf to change
  2091.  
  2092. # platform:  $XConsortium: sun.cf,v 1.71 91/12/20 11:18:34 rws Exp $
  2093.  
  2094. # operating system:  SunOS 4.1.1
  2095.  
  2096. # $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
  2097.  
  2098. # -------------------------------------------------------------------------
  2099. # site-specific configuration parameters that go after
  2100. # the platform-specific parameters - edit site.def to change
  2101.  
  2102. # site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
  2103.  
  2104.             SHELL = /bin/sh
  2105.  
  2106.               TOP = .
  2107.       CURRENT_DIR = .
  2108.  
  2109.                AR = ar cq
  2110.   BOOTSTRAPCFLAGS =
  2111.                CC = cc
  2112.                AS = as
  2113.  
  2114.          COMPRESS = compress
  2115.               CPP = /lib/cpp $(STD_CPP_DEFINES)
  2116.     PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
  2117.           INSTALL = install
  2118.                LD = ld
  2119.              LINT = lint
  2120.       LINTLIBFLAG = -C
  2121.          LINTOPTS = -axz
  2122.                LN = ln -s
  2123.              MAKE = make
  2124.                MV = mv
  2125.                CP = cp
  2126.  
  2127.            RANLIB = ranlib
  2128.   RANLIBINSTFLAGS =
  2129.  
  2130.                RM = rm -f
  2131.             TROFF = psroff
  2132.          MSMACROS = -ms
  2133.               TBL = tbl
  2134.               EQN = eqn
  2135.      STD_INCLUDES =
  2136.   STD_CPP_DEFINES =
  2137.       STD_DEFINES =
  2138.  EXTRA_LOAD_FLAGS =
  2139.   EXTRA_LIBRARIES =
  2140.              TAGS = ctags
  2141.  
  2142.     SHAREDCODEDEF = -DSHAREDCODE
  2143.          SHLIBDEF = -DSUNSHLIB
  2144.  
  2145.     PROTO_DEFINES =
  2146.  
  2147.      INSTPGMFLAGS = -s
  2148.  
  2149.      INSTBINFLAGS = -m 0755
  2150.      INSTUIDFLAGS = -m 4755
  2151.      INSTLIBFLAGS = -m 0644
  2152.      INSTINCFLAGS = -m 0444
  2153.      INSTMANFLAGS = -m 0444
  2154.      INSTDATFLAGS = -m 0444
  2155.     INSTKMEMFLAGS = -g kmem -m 2755
  2156.  
  2157.       PROJECTROOT = /usr/local/X11
  2158.  
  2159.      TOP_INCLUDES = -I$(INCROOT)
  2160.  
  2161.       CDEBUGFLAGS = -O
  2162.         CCOPTIONS = -pipe
  2163.  
  2164.       ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
  2165.        ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
  2166.            CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
  2167.         LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
  2168.  
  2169.            LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  2170.  
  2171.         LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
  2172.  
  2173.    LDCOMBINEFLAGS = -X -r
  2174.       DEPENDFLAGS =
  2175.  
  2176.         MACROFILE = sun.cf
  2177.            RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
  2178.  
  2179.     IMAKE_DEFINES =
  2180.  
  2181.          IRULESRC = $(CONFIGDIR)
  2182.         IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
  2183.  
  2184.      ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
  2185.             $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
  2186.             $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
  2187.  
  2188. # -------------------------------------------------------------------------
  2189. # X Window System Build Parameters
  2190. # $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
  2191.  
  2192. # -------------------------------------------------------------------------
  2193. # X Window System make variables; this need to be coordinated with rules
  2194.  
  2195.           PATHSEP = /
  2196.         USRLIBDIR = /usr/local/X11/lib
  2197.            BINDIR = /usr/local/X11/bin
  2198.           INCROOT = /usr/local/X11/include
  2199.      BUILDINCROOT = $(TOP)
  2200.       BUILDINCDIR = $(BUILDINCROOT)/X11
  2201.       BUILDINCTOP = ..
  2202.            INCDIR = $(INCROOT)/X11
  2203.            ADMDIR = /usr/adm
  2204.            LIBDIR = $(USRLIBDIR)/X11
  2205.         CONFIGDIR = $(LIBDIR)/config
  2206.        LINTLIBDIR = $(USRLIBDIR)/lint
  2207.  
  2208.           FONTDIR = $(LIBDIR)/fonts
  2209.          XINITDIR = $(LIBDIR)/xinit
  2210.            XDMDIR = $(LIBDIR)/xdm
  2211.            TWMDIR = $(LIBDIR)/twm
  2212.           MANPATH = /usr/local/X11/man
  2213.     MANSOURCEPATH = $(MANPATH)/man
  2214.         MANSUFFIX = 1
  2215.      LIBMANSUFFIX = 3
  2216.            MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
  2217.         LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
  2218.            NLSDIR = $(LIBDIR)/nls
  2219.         PEXAPIDIR = $(LIBDIR)/PEX
  2220.       XAPPLOADDIR = $(LIBDIR)/app-defaults
  2221.        FONTCFLAGS = -t
  2222.  
  2223.      INSTAPPFLAGS = $(INSTDATFLAGS)
  2224.  
  2225.             IMAKE = imake
  2226.            DEPEND = makedepend
  2227.               RGB = rgb
  2228.  
  2229.             FONTC = bdftopcf
  2230.  
  2231.         MKFONTDIR = mkfontdir
  2232.         MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
  2233.  
  2234.         CONFIGSRC = $(TOP)/config
  2235.        DOCUTILSRC = $(TOP)/doc/util
  2236.         CLIENTSRC = $(TOP)/clients
  2237.           DEMOSRC = $(TOP)/demos
  2238.            LIBSRC = $(TOP)/lib
  2239.           FONTSRC = $(TOP)/fonts
  2240.        INCLUDESRC = $(TOP)/X11
  2241.         SERVERSRC = $(TOP)/server
  2242.           UTILSRC = $(TOP)/util
  2243.         SCRIPTSRC = $(UTILSRC)/scripts
  2244.        EXAMPLESRC = $(TOP)/examples
  2245.        CONTRIBSRC = $(TOP)/../contrib
  2246.            DOCSRC = $(TOP)/doc
  2247.            RGBSRC = $(TOP)/rgb
  2248.         DEPENDSRC = $(UTILSRC)/makedepend
  2249.          IMAKESRC = $(CONFIGSRC)
  2250.          XAUTHSRC = $(LIBSRC)/Xau
  2251.           XLIBSRC = $(LIBSRC)/X
  2252.            XMUSRC = $(LIBSRC)/Xmu
  2253.        TOOLKITSRC = $(LIBSRC)/Xt
  2254.        AWIDGETSRC = $(LIBSRC)/Xaw
  2255.        OLDXLIBSRC = $(LIBSRC)/oldX
  2256.       XDMCPLIBSRC = $(LIBSRC)/Xdmcp
  2257.       BDFTOSNFSRC = $(FONTSRC)/bdftosnf
  2258.       BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
  2259.       BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
  2260.      MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
  2261.          FSLIBSRC = $(FONTSRC)/lib/fs
  2262.     FONTSERVERSRC = $(FONTSRC)/server
  2263.      EXTENSIONSRC = $(TOP)/extensions
  2264.          XILIBSRC = $(EXTENSIONSRC)/lib/xinput
  2265.       PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
  2266.  
  2267. # $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
  2268.  
  2269. SHLIBLDFLAGS = -assert pure-text
  2270. PICFLAGS = -pic
  2271.  
  2272.   DEPEXTENSIONLIB =
  2273.      EXTENSIONLIB = -lXext
  2274.  
  2275.           DEPXLIB = $(DEPEXTENSIONLIB)
  2276.              XLIB = $(EXTENSIONLIB) -lX11
  2277.  
  2278.         DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
  2279.        XMULIBONLY = -lXmu
  2280.            XMULIB = -lXmu
  2281.  
  2282.        DEPOLDXLIB =
  2283.           OLDXLIB = -loldX
  2284.  
  2285.       DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
  2286.          XTOOLLIB = -lXt
  2287.  
  2288.         DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
  2289.            XAWLIB = -lXaw
  2290.  
  2291.         DEPXILIB =
  2292.            XILIB = -lXi
  2293.  
  2294.         SOXLIBREV = 4.10
  2295.           SOXTREV = 4.10
  2296.          SOXAWREV = 5.0
  2297.         SOOLDXREV = 4.10
  2298.          SOXMUREV = 4.10
  2299.         SOXEXTREV = 4.10
  2300.       SOXINPUTREV = 4.10
  2301.  
  2302.       DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
  2303.          XAUTHLIB =  -lXau
  2304.       DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
  2305.          XDMCPLIB =  -lXdmcp
  2306.  
  2307.         DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
  2308.            PHIGSLIB =  -lphigs
  2309.  
  2310.        DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
  2311.           XBSDLIB =  -lXbsd
  2312.  
  2313.  LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
  2314.          LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
  2315.           LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
  2316.         LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
  2317.           LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
  2318.            LINTXI = $(LINTLIBDIR)/llib-lXi.ln
  2319.         LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
  2320.  
  2321.           DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
  2322.  
  2323.          DEPLIBS1 = $(DEPLIBS)
  2324.          DEPLIBS2 = $(DEPLIBS)
  2325.          DEPLIBS3 = $(DEPLIBS)
  2326.  
  2327. # -------------------------------------------------------------------------
  2328. # Imake rules for building libraries, programs, scripts, and data files
  2329. # rules:  $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
  2330.  
  2331. # -------------------------------------------------------------------------
  2332. # start of Imakefile
  2333.  
  2334. LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
  2335. SRCS1= Goban.c xigc.c filter.c pipes.c board.c
  2336. OBJS1= Goban.o xigc.o filter.o pipes.o board.o
  2337.  
  2338. SRCS2= igscomm.c
  2339. OBJS2= igscomm.o
  2340.  
  2341. PROGRAMS = xigc igscomm
  2342.  
  2343.  OBJS = $(OBJS1) $(OBJS2) $(OBJS3)
  2344.  SRCS = $(SRCS1) $(SRCS2) $(SRCS3)
  2345.  
  2346. all:: $(PROGRAMS)
  2347.  
  2348. xigc: $(OBJS1) $(DEPLIBS1)
  2349.     $(RM) $@
  2350.     $(CC) -o $@ $(LDOPTIONS) $(OBJS1)  $(LOCAL_LIBRARIES) $(LDLIBS)   $(EXTRA_LOAD_FLAGS)
  2351.  
  2352. install:: xigc
  2353.     @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
  2354.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
  2355.     $(INSTALL) -c $(INSTPGMFLAGS)  xigc $(DESTDIR)$(BINDIR)
  2356.  
  2357. install.man:: xigc.man
  2358.     @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
  2359.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
  2360.     $(INSTALL) -c $(INSTMANFLAGS) xigc.man $(DESTDIR)$(MANDIR)/xigc.$(MANSUFFIX)
  2361.  
  2362. saber_xigc:: $(SRCS1)
  2363.     # load $(ALLDEFINES) $(SRCS1)  $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  2364.  
  2365. osaber_xigc:: $(OBJS1)
  2366.     # load $(ALLDEFINES) $(OBJS1)  $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  2367.  
  2368. depend::
  2369.     $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
  2370.  
  2371. lint:
  2372.     $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
  2373. lint1:
  2374.     $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
  2375.  
  2376. clean::
  2377.     $(RM) $(PROGRAMS)
  2378.  
  2379. igscomm: $(OBJS2) $(DEPLIBS2)
  2380.     $(RM) $@
  2381.     $(CC) -o $@ $(LDOPTIONS) $(OBJS2)  $(LDLIBS)   $(EXTRA_LOAD_FLAGS)
  2382.  
  2383. saber_igscomm:: $(SRCS2)
  2384.     # load $(ALLDEFINES) $(SRCS2)  $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  2385.  
  2386. osaber_igscomm:: $(OBJS2)
  2387.     # load $(ALLDEFINES) $(OBJS2)  $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  2388.  
  2389. install:: igscomm
  2390.     @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
  2391.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
  2392.     $(INSTALL) -c $(INSTPGMFLAGS)  igscomm $(DESTDIR)$(BINDIR)
  2393.  
  2394. install.man:: igscomm.man
  2395.     @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
  2396.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
  2397.     $(INSTALL) -c $(INSTMANFLAGS) igscomm.man $(DESTDIR)$(MANDIR)/igscomm.$(MANSUFFIX)
  2398.  
  2399. install:: XIgc.ad
  2400.     @if [ -d $(DESTDIR)$(XAPPLOADDIR) ]; then set +x; \
  2401.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(XAPPLOADDIR)); fi
  2402.     $(INSTALL) -c $(INSTAPPFLAGS) XIgc.ad $(DESTDIR)$(XAPPLOADDIR)/XIgc
  2403.  
  2404. install.man:: xigc.man
  2405.     @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
  2406.     else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
  2407.     $(INSTALL) -c $(INSTMANFLAGS) xigc.man $(DESTDIR)$(MANDIR)/xigc.$(MANSUFFIX)
  2408.  
  2409. # -------------------------------------------------------------------------
  2410. # common rules for all Makefiles - do not edit
  2411.  
  2412. emptyrule::
  2413.  
  2414. clean::
  2415.     $(RM_CMD) "#"*
  2416.  
  2417. Makefile::
  2418.     -@if [ -f Makefile ]; then set -x; \
  2419.     $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
  2420.     else exit 0; fi
  2421.     $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
  2422.  
  2423. tags::
  2424.     $(TAGS) -w *.[ch]
  2425.     $(TAGS) -xw *.[ch] > TAGS
  2426.  
  2427. saber:
  2428.     # load $(ALLDEFINES) $(SRCS)
  2429.  
  2430. osaber:
  2431.     # load $(ALLDEFINES) $(OBJS)
  2432.  
  2433. # -------------------------------------------------------------------------
  2434. # empty rules for directories that do not have SUBDIRS - do not edit
  2435.  
  2436. install::
  2437.     @echo "install in $(CURRENT_DIR) done"
  2438.  
  2439. install.man::
  2440.     @echo "install.man in $(CURRENT_DIR) done"
  2441.  
  2442. Makefiles::
  2443.  
  2444. includes::
  2445.  
  2446. # -------------------------------------------------------------------------
  2447. # dependencies generated by makedepend
  2448.  
  2449. SHAR_EOF
  2450. fi
  2451. if test -f 'README'
  2452. then
  2453.     echo shar: "will not over-write existing file 'README'"
  2454. else
  2455. cat << \SHAR_EOF > 'README'
  2456. This is xigc Release v2.1 of 1/93
  2457.  
  2458. ========================================================================
  2459.  
  2460. See "xigc.man" for full documentation and installation instructions.
  2461. Use "nroff -man xigc.man" to look at the file at your terminal, or
  2462. something like "troff -man xigc.man | lpr" to print it at your printer.
  2463.  
  2464. Installation instructions:
  2465.  
  2466. After unpacking the source distribution, use "xmkmf" followed by
  2467. "make depend" to generate a Makefile for your environment.  
  2468. If you do not have "xmkmf" or "imake," you may be able to adapt the file
  2469. "Makefile.hand," and use it as a Makefile for your system.  Then type
  2470. "make" and then "make install" to install xigc and igscomm in your
  2471. standard locations.
  2472.  
  2473. Make sure the file "XIgc.ad" is placed in your standard place for X11
  2474. application defaults (and named "XIgc") or added to your ".Xdefaults."
  2475. You can also do "xrdb -merge XIgc.ad" after you start X but before
  2476. running xigc.  You must do one of these things or xigc will not run!
  2477. "make install" should install this file correctly.
  2478.  
  2479. ========================================================================
  2480.     
  2481. Known Bugs and Major Problems:
  2482.     1.  This release includes several patches to help solve the "spinning
  2483.         telnet" or "hanging server" problem.  BUT:  There are still
  2484.         pathological cases where xigc can die leaving the telnet
  2485.         process running.  I STRONGLY recommend that you use igscomm
  2486.         instead of telnet as your communications program with xigc,
  2487.         as igscomm is not subject to this serious problem.
  2488.     2.  Sometimes a move is lost during Refresh(Host):  move 29 and/or 62,
  2489.         92, 128.  Never other moves apparently.  This only happens
  2490.         with telnet, and is another reason to use igscomm instead
  2491.         of telnet.
  2492.     3.  xigc should compile and run correctly with any installation of
  2493.         MIT X11R4 or X11R5 on any machine (including VMS!).  However,
  2494.         it seems that some IBM and DEC versions of X do not include
  2495.         the libXaw (Arrogant IBM thinks that their stupid Motif
  2496.         widgets replace the Athena widgets).  Also, xigc may not
  2497.         compile or run on X11R3 or earlier releases of X, or on some
  2498.         versions of SVR3 for 386 machines.  I have also heard some
  2499.         problems compiling on AIX 3.1, though 3.15 and 3.2 should
  2500.         work if you have the Athena widgets.  In any case, you should
  2501.         try building xigc anyway; it might work....
  2502.     4.  The second-by-second timer is a LOCAL timer in the xigc
  2503.         application.  It is only an approximation of the official
  2504.         time, which is kept by the server.  The time display may
  2505.         differ by a few seconds from the official time under some
  2506.         conditions.
  2507.     5.  Some systems are set up with a gateway, so that your machine
  2508.         is not directly connected to the internet.  Many universities
  2509.         and large businesses do this.  In this case, the local
  2510.         version of telnet connects first to the gateway, then out
  2511.         over the internet to IGS.  If you have this type of setup,
  2512.         you will not be able to use igscomm.  Normally when this
  2513.         happens xigc will just end immediately, possibly with a
  2514.         message like "host 128... not found."  If this happens to
  2515.         you, you will have to use telnet for your communications
  2516.         program with xigc.  You can continue to use the xigc "-c"
  2517.         command-line option, or place your communications command
  2518.         line in your .xigcrc file.  See xigc.man for more information.
  2519.         You might also be able to use "rlogin" or "cu" to connect to
  2520.         your gateway machine, and then run igscomm from there.
  2521.     6.  Some systems have some problems with the feature that allows
  2522.         you to type to the IGS command processor while the mouse
  2523.         cursor is over the board or menu window.  If you get an
  2524.         error message like this when you start xigc:
  2525.  
  2526.         X Error of failed request: BadAccess (attempt to access
  2527.             private resource denied)
  2528.         Major opcode of failed request:  33 (X_GrabKey)
  2529.         Serial number of failed request:  xxx
  2530.         Current serial number in output stream:  xxx
  2531.  
  2532.         If you see this message, you will have to recompile xigc.
  2533.         Edit the file xigc.c, and uncomment the line
  2534.  
  2535.         #ifndef NOKEYGRAB
  2536.  
  2537.         near the top of xigc.c.  Then recompile.  This will disable
  2538.         the feature, but will allow xigc to run on your machine.
  2539.     7.  If you have the board size too small (smaller than about 400
  2540.         pixels), the end-of-game scoring will not appear.  This is
  2541.         an automatic feature of the Goban widget.  To see the scoring
  2542.         marks, you can use a larger board or select a smaller font
  2543.         in your application defaults.
  2544.  
  2545. =======================================================================
  2546.  
  2547. Other Bugs, New Features and Improvements Needed:
  2548.     1.  Get passwd (cntrl-P) handling for xterm window
  2549.         integrate chars coming in via stdin with chars coming in
  2550.         via X
  2551.     2.  stipple in config file or X resource?
  2552.         1.  All config stuff in X resources?
  2553.     3.  thist output sometimes munged.
  2554.     4.  Better sgf save of button 3 variations?
  2555.     5.  Display komi and player rank in xigc menu
  2556.     6.  Beep or other warning at 1 minute before time runs out?
  2557.         Or user can set beep interval in config file?
  2558.     7.  Board size in app defaults; support other than 9, 13, and 19 lines?
  2559.     8.  observeoff in menu; switch game with "observe n" so observeoff
  2560.         not always required?
  2561.     9.  Include komi in final end-of-game point count?
  2562.  
  2563. =======================================================================
  2564.  
  2565. Changes in xigc from v2.0 to v2.1:
  2566.     1.  Fix so xigc does not try to change game numbers automatically.
  2567.     2.  Fix several minor bugs.
  2568.     3.  Remove last move dot for "status" display.
  2569.     4.  Fix several bugs in sgf save format.
  2570.     5.  Upgrade support for "status" "look" and "translate" to chase
  2571.         the latest IGS changes.
  2572.     6.  Fix a bug that occasionally caused xigc to exit unexpectedly
  2573.         during "Refresh (Host)" of games with more than about
  2574.         180 moves.
  2575.     7.  Force 7-bit characters so xigc works correctly with 8-bit
  2576.         communications programs and modems.
  2577.  
  2578. Changes in xigc from v1.9 to v2.0:
  2579.     1.  Fix several minor bugs.
  2580.     2.  Fix bug that caused multiple undos that include replacing
  2581.         captured stones to not redraw screen correctly.
  2582.     3.  Fix problem with move numbering when saving games with
  2583.         "Save to Current"
  2584.     4.  Improve file handling during Save Game.
  2585.     5.  Add more app-defaults to control window size, font, etc,
  2586.         for the Menu window.
  2587.  
  2588. Changes in xigc from v1.8 to v1.9:
  2589.     1.  Fix bug that caused real incoming moves to participate in
  2590.         captures during button 3 sequences.
  2591.     2.  Fix Imakefile problem that caused NullParameter error during
  2592.         make on X11R4 systems.
  2593.     3.  Fix bug that prevented setting sgf format in .xigcrc file.
  2594.     4.  Upgrade end-of-game processing to show final board with
  2595.         scored points marked.
  2596.     5.  Fix several minor bugs.
  2597.  
  2598. Changes in xigc from v1.0 to v1.8:
  2599.     1.  Add explicit kill for comm program when xigc exits, and several
  2600.         other fixes related to the "spinning telnet" or "hanging
  2601.         server" problem.  But, I strongly recommend that "igscomm"
  2602.         is used instead of telnet for communications with xigc.
  2603.         igscomm is not subject to the hanging server problem, since
  2604.         it exits when xigc exits.
  2605.     2.  Fix many minor bugs.
  2606.     3.  Remove gameSize default from XIgc.ad.  It is hardcoded to
  2607.         default to 19.
  2608.     4.  Add second-by-second timer.
  2609.     5.  Add ability to type to IGS command processor while mouse is in
  2610.         board or menu windows.  You can also type CNTRL-P to shut off
  2611.         echoing for a line (this allows passwords to not print).
  2612.         The CNTRL-P feature currently only works when the cursor is
  2613.         over the board or menu, NOT when the cursor is in the text
  2614.         window.  Thanks to loganj@byu.edu for providing some sample
  2615.         code implementing this feature.
  2616.     6.  Upgrade to latest version of the Goban widget.  This fixes some
  2617.         cases where the cursor was an empty circle inside a square,
  2618.         rather than an image of white or black stone.
  2619.     7.  Add a config file to put comm command line, so it is not required
  2620.         on xigc command line or compiled in.
  2621.     8.  Add ability to save game in text format or SGF format.
  2622.     9.  Much improved game analysis functions, including the ability to
  2623.         step through games move-by-move, to add stones to the board
  2624.         from any move position, and to refresh to the current "step"
  2625.         or to the current "real" game position.
  2626.     10. Much improved end-of-game and scoring support.
  2627.     11. Support for the IGS "status" command.  You can now look at the
  2628.         current board position of another game while playing or
  2629.         observing.
  2630.  
  2631.  
  2632. Changes in xigc from v0.9 to v1.0:
  2633.     
  2634.     1.  Fix a bug where dead stones were not always picked up correctly
  2635.         on the first "refresh" after xigc started.
  2636.     2.  Add an app default to select whether button 3 moves are
  2637.         saved locally or not.
  2638.     3.  Fix handling of "Pass" during games.
  2639.     4.  Get rid of junk line that was printed when Bell is enabled at IGS.
  2640.     5.  Fix some char passing problems in igscomm.
  2641.     6.  Add the ability for igscomm to suppress local echo.
  2642.     7.  Add code to make "refresh" command do something useful.
  2643.     8.  Make "Pass" and "undo" moves appear in "Last:" window item.
  2644.  
  2645.  
  2646. Changes in xigc from v0.8 to v0.9:
  2647.  
  2648.     1.  Add a simple Makefile so that users without imake or xmkmf have
  2649.         a chance.
  2650.     2.  Fix a bug associated with getopt() on the IBM RS6000.
  2651.     3.  Change the default command from "telnet lacerta.unm.edu 6969"
  2652.         to "telnet 129.24.14.70 6969".
  2653.     4.  Clear and refresh the board when starting to play a game.
  2654.     5.  Button 3 sequences are no longer saved as part of the game, and
  2655.         are cleared with "Refresh (Local)".  This also means that
  2656.         they are not saved to a file with "Save Moves".
  2657.     6.  Change the "highlite" on the last-played stone so it stays
  2658.         centered better for all board dimensions.
  2659.     7.  Disable the "Quit" menu item when the "-c" command-line option is
  2660.         used, since xigc will not know how to exit cleanly from any
  2661.         random user-specified communications command.
  2662.     8.  Add a stipple-gray board background selected by command-line
  2663.         option or app default.  You have a compile-time choice of
  2664.         either of two stipple patterns.
  2665.     9.  Fix the declaration of "time_t" so it compiles on SGI machines.
  2666.  
  2667. =======================================================================
  2668. SHAR_EOF
  2669. fi
  2670. if test -f 'XIgc.ad'
  2671. then
  2672.     echo shar: "will not over-write existing file 'XIgc.ad'"
  2673. else
  2674. cat << \SHAR_EOF > 'XIgc.ad'
  2675. XIgc*goban*foreground         : black
  2676. XIgc*goban*blackStoneBackground         : black
  2677. XIgc*goban*blackStoneForeground         : white
  2678. XIgc*goban*whiteStoneBackground         : white
  2679. XIgc*goban*whiteStoneForeground         : black
  2680. XIgc*goban*blackStoneBorder   : black
  2681. XIgc*Goban*whiteStoneBorder   : black
  2682. XIgc*goban*autoRedisplay      : true
  2683. XIgc*goban*background         : tan1
  2684. XIgc*goban*stipple          : false
  2685. XIgc*goban*borderWidth        : 2
  2686. XIgc*goban*displayCoordinates : true
  2687. XIgc*font                     : -adobe-new century schoolbook-bold-r-*-*-12-*-*-*-*-*-*-*
  2688. XIgc*goban*font               : -adobe-new century schoolbook-bold-r-*-*-12-*-*-*-*-*-*-*
  2689. XIgc*goban*pointSize          : 24
  2690. XIgc*goban*viewBottom         : 3
  2691. XIgc*goban*viewLeft           : 5
  2692. XIgc*goban*viewRight          : 9
  2693. XIgc*goban*width              : 400
  2694. XIgc*goban*height             : 400
  2695. XIgc*goban*viewTop            : 12
  2696. XIgc*board.geometry           : -1+1
  2697. XIgc*Goban.translations       : #augment \n\
  2698.                    <Btn1Down> : inputStone() \n\
  2699.                    <Btn2Down> : removeStone() \n\
  2700.                    <Btn3Down> : addStone()
  2701.  
  2702. XIgc*geometry                 : -1-1
  2703. XIgc*background               : tan1
  2704. XIgc*Label*foreground         : black
  2705. XIgc*Command*foreground       : blue
  2706. XIgc*Command*width            : 148
  2707. XIgc*Label*width              : 148
  2708. XIgc*lastw.width              : 302
  2709.  
  2710. XIgc*refresh.label            : Refresh (Host)
  2711. XIgc*cursorcolor.label        : Change Color
  2712. XIgc*clearb.label             : Clear
  2713. XIgc*stepf.label              : Step Forward
  2714. XIgc*stepb.label              : Step Back
  2715. XIgc*refreshstep.label        : Refresh to Step
  2716. XIgc*localrefresh.label       : Refresh (Local)
  2717. XIgc*size.label               : Change Size
  2718. XIgc*savegame.label           : Save Game
  2719. XIgc*savecurrent.label        : Save to Current
  2720. XIgc*coordinates.label        : Display Coordinates
  2721. XIgc*quit.label               : Quit
  2722.  
  2723. XIgc*hcapw.fromHoriz          : gamew
  2724. XIgc*whitew.fromVert          : gamew
  2725. XIgc*blackw.fromVert          : gamew
  2726. XIgc*blackw.fromHoriz         : whitew
  2727. XIgc*captw.fromVert           : whitew
  2728. XIgc*captb.fromVert           : blackw
  2729. XIgc*captb.fromHoriz          : captw
  2730. XIgc*timew.fromVert           : captw
  2731. XIgc*timeb.fromVert           : captb
  2732. XIgc*timeb.fromHoriz          : timew
  2733. XIgc*lastw.fromVert           : timew
  2734.  
  2735. XIgc*refresh.fromVert         : lastw
  2736. XIgc*cursorcolor.fromVert     : refresh
  2737. XIgc*clearb.fromVert          : cursorcolor
  2738. XIgc*stepf.fromVert           : clearb
  2739. XIgc*stepb.fromVert           : stepf
  2740. XIgc*refreshstep.fromVert     : stepb
  2741. XIgc*localrefresh.fromVert    : lastw
  2742. XIgc*localrefresh.fromHoriz   : refresh
  2743. XIgc*size.fromVert            : localrefresh
  2744. XIgc*size.fromHoriz          : cursorcolor
  2745. XIgc*savegame.fromVert        : size
  2746. XIgc*savegame.fromHoriz          : clearb
  2747. XIgc*savecurrent.fromVert     : savegame
  2748. XIgc*savecurrent.fromHoriz    : stepf
  2749. XIgc*coordinates.fromVert     : savecurrent
  2750. XIgc*coordinates.fromHoriz    : stepb
  2751. XIgc*quit.fromVert            : coordinates
  2752. XIgc*quit.fromHoriz           : refreshstep
  2753. SHAR_EOF
  2754. fi
  2755. if test -f 'blackstone.bm'
  2756. then
  2757.     echo shar: "will not over-write existing file 'blackstone.bm'"
  2758. else
  2759. cat << \SHAR_EOF > 'blackstone.bm'
  2760. #define blackstone_width 16
  2761. #define blackstone_height 16
  2762. #define blackstone_x_hot 7
  2763. #define blackstone_y_hot 8
  2764. static unsigned char blackstone_bits[] = {
  2765.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  2766.    0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0xfe, 0x77, 0xfe, 0x7b,
  2767.    0xfc, 0x3c, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  2768. SHAR_EOF
  2769. fi
  2770. if test -f 'board.c'
  2771. then
  2772.     echo shar: "will not over-write existing file 'board.c'"
  2773. else
  2774. cat << \SHAR_EOF > 'board.c'
  2775. /* board.c
  2776.  * S.Coffin    USWAT    1/93
  2777.  *
  2778.  * adapted from adrian@u.washington.edu [with significant changes]
  2779.  * keeps local copy of board state, dead stone removal, handicaps, etc
  2780.  */
  2781.  
  2782. #include <stdio.h>
  2783. #include <time.h>
  2784. #include "shared.h"
  2785. #include "filter.h"
  2786.  
  2787. extern int drawStone();
  2788. extern int move, currentmove;
  2789. extern int boardchanged, mouseflag;
  2790. extern int beep();
  2791. static int tt;
  2792. void removeStones();
  2793.  
  2794. typedef char boardtype[20][20];
  2795. int prisoners[2], stepprisoners[2];
  2796.  
  2797. struct movelist {
  2798.    int x, y;
  2799.    unsigned char flag;
  2800. };
  2801.  
  2802. static struct movelist realmovelist[MAXMOVE], stepmovelist[MAXMOVE];
  2803.  
  2804. boardtype board, stepboard;
  2805.  
  2806. #define boolean unsigned char
  2807. #define false 0
  2808. #define true 1
  2809.  
  2810. #define piece char
  2811.  
  2812. static int boardsize = 19;
  2813.  
  2814.  
  2815. clearboard( b, pris )
  2816.     boardtype b;
  2817.     int *pris;
  2818. {
  2819.     int i, j;
  2820.     pris[0] = pris[1] = 0;
  2821.     for (i = 0; i < boardsize; i++)
  2822.     for (j = 0; j < boardsize; j++)
  2823.         b[i][j] = EMPTY;
  2824. }
  2825.  
  2826. clear_stepboard() {
  2827.     clearboard(stepboard, stepprisoners);
  2828. }
  2829.  
  2830. initboard( size )
  2831.     char size;
  2832. {
  2833.     boardsize = size;
  2834.     clearboard(board, prisoners);
  2835.     clearboard(stepboard, stepprisoners);
  2836. }
  2837.  
  2838. char *stamptime()
  2839. {
  2840.     char *asctime();                /* stuff to get timestamp */
  2841.     struct tm *localtime(), *tp;
  2842.     struct timeval tv;
  2843.     struct timezone tz;
  2844.  
  2845.     gettimeofday (&tv, &tz);                /* fill in timestamp */
  2846.     tp = localtime ((time_t *)&tv.tv_sec);
  2847.     return(asctime(tp));
  2848. }
  2849.  
  2850. /* save game in sgf format */
  2851. save_game_sgf( s, p1, p2, hcap, type )
  2852.     char *s;    /* file name to save to */
  2853.     char *p1, *p2;    /* player names */
  2854.     int hcap;    /* handicap stones or 0 */
  2855.     int type;    /* save REALMOVES or STEPMOVES */
  2856. {
  2857.     FILE *fp;
  2858.     int i, x, y;
  2859.     char *str;
  2860.     int m;
  2861.     struct movelist *ml;
  2862.  
  2863.     if( type == REALMOVE ) {
  2864.         m = move;
  2865.         ml = realmovelist;
  2866.     }
  2867.     else if( type == STEPMOVE ) {
  2868.         m = currentmove;
  2869.         ml = stepmovelist;
  2870.     }
  2871.  
  2872.     if( (fp = fopen( s, "a+" )) == NULL ) {
  2873.         perror( "savegame" );
  2874.         return( 0 );
  2875.     }
  2876.     fprintf( fp, "(\n;\nPlayerBlack[%s]\nPlayerWhite[%s]\n",
  2877.             p2, p1 );
  2878.     str = stamptime();
  2879.     str[strlen(str)-1] = '\0';
  2880.     fprintf( fp, "GaMe[1]\n" );
  2881.     fprintf( fp, "VieW[]\n" );
  2882.     fprintf( fp, "EVent[]\n" );
  2883.     fprintf( fp, "DaTe[%s]\n", str );
  2884.     fprintf( fp, "SiZe[%d]\n", boardsize );
  2885.     fprintf( fp, "PlaCe[IGS]\n", boardsize );
  2886.     if( hcap ) fprintf( fp, "HAndicap[%d]\n", hcap );
  2887.     fprintf( fp, "KoMi[??]\n" );
  2888.     fprintf( fp, "USer[File created by IGS and xigc]\n" );
  2889.  
  2890.     if( hcap != 0 ) {
  2891.         sgf_hcap( fp, boardsize, hcap );
  2892.         i = 1;
  2893.     }
  2894.     else i = 0;
  2895.  
  2896.     fprintf( fp, ";\n" );
  2897.  
  2898.     for( ; i <= m; ++i ) {
  2899.         x = ml[i].x + 1;
  2900.         y = ml[i].y + 1;
  2901.         if( x < 0 ) {        /* pass */
  2902.             fprintf( fp, "%s[tt]\n;\n", (i%2) ? "White" : "Black" );
  2903.         }
  2904.         else {            /* real move */
  2905.             fprintf( fp, "%s[%c%c]\n;\n", (i%2) ? "White" : "Black",
  2906.                 'a' + (char)x - 1,
  2907.                 'a' + (char)(19 - y) );
  2908.         }
  2909.     }
  2910.  
  2911.     fprintf( fp, ")\n" );
  2912.  
  2913.     fclose( fp );
  2914.     return( 1 );
  2915. }
  2916.  
  2917. /* save the moves in a file */
  2918. save_game( s, p1, p2, hcap, type )
  2919.     char *s;    /* file name to save to */
  2920.     char *p1, *p2;    /* player names */
  2921.     int hcap;    /* handicap stones or 0 */
  2922.     int type;    /* save REALMOVE or STEPMOVE */
  2923. {
  2924.     FILE *fp;
  2925.     int i, x, y;
  2926.     int m;
  2927.     struct movelist *ml;
  2928.  
  2929.     if( type == REALMOVE ) {
  2930.        m = move;
  2931.        ml = realmovelist;
  2932.     }
  2933.     else if( type == STEPMOVE ) {
  2934.        m = currentmove;
  2935.        ml = stepmovelist;
  2936.     }
  2937.  
  2938.     if( (fp = fopen( s, "a+" )) == NULL ) {
  2939.         perror( "savegame" );
  2940.         return( 0 );
  2941.     }
  2942.  
  2943.     fprintf( fp, "\n%s\n", stamptime() );
  2944.     fprintf( fp, "White: %s\nBlack: %s\n", p1, p2 );
  2945.     fprintf( fp, "Handicap: %d\n\n", hcap );
  2946.  
  2947.     if( hcap != 0 ) {
  2948.         fprintf( fp, "  0 (B): Handicap %d\n", hcap );
  2949.         i = 1;
  2950.     }
  2951.     else i = 0;
  2952.  
  2953.     for( ; i <= m; ++i ) {
  2954.         x = ml[i].x + 1;
  2955.         y = ml[i].y + 1;
  2956.         fprintf( fp, "%3d (%c):  ", i, (i%2) ? 'W' : 'B' );
  2957.         if( x < 0 ) fprintf( fp, "Pass\n" );
  2958.         else fprintf( fp, "%c%d\n", 'A' + ((x > 8) ? x + 1 : x) - 1, y );
  2959.     }
  2960.     fclose( fp );
  2961.     return( 1 );
  2962. }
  2963.  
  2964. boolean inRange( i, j )
  2965.     int i, j;
  2966. {
  2967.    return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
  2968. }
  2969.  
  2970. boolean alive0( b, m, i, j, t )
  2971.     boardtype b;
  2972.     boardtype m;
  2973.     int i, j;
  2974.     piece t;
  2975. {
  2976.     piece pt;
  2977.  
  2978.     pt = b[i][j];
  2979.     if ((pt != EMPTY && pt != t) || m[i][j] != EMPTY) return 0;
  2980.     m[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
  2981.     if (pt == EMPTY) return 1;
  2982.     return( j < boardsize - 1 && alive0(b, m, i, j + 1, t)) ||
  2983.         (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) ||
  2984.         (i && alive0(b, m, i - 1, j, t)) ||
  2985.         (j && alive0(b, m, i, j - 1, t));
  2986. }
  2987.  
  2988. /* Does group at i,j have liberties? */
  2989. boolean alive( b, i, j )
  2990.     boardtype b;
  2991.     int i, j;
  2992. {
  2993.     boardtype m;
  2994.     int p[2];
  2995.  
  2996.     clearboard(m, p);
  2997.     return( alive0(b, m, i, j, b[i][j]) );
  2998. }
  2999.  
  3000.  
  3001. void removeStones0( b, pris, i, j, t )
  3002.     boardtype b;
  3003.     int *pris;
  3004.     int i, j;
  3005.     piece t;
  3006. {
  3007.     if (b[i][j] != t) return;
  3008.     b[i][j] = EMPTY;
  3009.  
  3010.     if( tt == REALMOVE ) {
  3011.         if( !boardchanged && !mouseflag ) {
  3012.             drawStone( i+1, j+1, EMPTY, TRUE );
  3013.         }
  3014.     }
  3015.     else if( tt == STEPMOVE ) {
  3016.         if( boardchanged || mouseflag ) {
  3017.             drawStone( i+1, j+1, EMPTY, TRUE );
  3018.         }
  3019.     }
  3020.  
  3021.     pris[t - 1]++;
  3022.     if( j < boardsize - 1 ) removeStones0( b, pris, i, j + 1, t );
  3023.     if( i < boardsize - 1 ) removeStones0( b, pris, i + 1, j, t );
  3024.     if( i ) removeStones0( b, pris, i - 1, j, t );
  3025.     if( j ) removeStones0( b, pris, i, j - 1, t );
  3026. }
  3027.  
  3028. void get_prisoners( x, y )
  3029.     int *x, *y;
  3030. {
  3031.     *x = stepprisoners[0];
  3032.     *y = stepprisoners[1];
  3033. }
  3034.  
  3035. void set_prisoners( x, y )
  3036.     int x, y;
  3037. {
  3038.     stepprisoners[0] = x;
  3039.     stepprisoners[1] = y;
  3040. }
  3041.  
  3042. void update_prisoners( x, y )
  3043.     int x, y;
  3044. {
  3045.     stepprisoners[0] += x;
  3046.     stepprisoners[1] += y;
  3047. }
  3048.  
  3049. void score_it( i, j )
  3050.     int i, j;
  3051. {
  3052.     --i;
  3053.     --j;
  3054.  
  3055.     tt = STEPMOVE;
  3056.     boardchanged = TRUE;
  3057.     removeStones( stepboard, stepprisoners, i, j );
  3058. }
  3059.  
  3060. void removeStones( b, pris, i, j )
  3061.     boardtype b;
  3062.     int *pris;
  3063.     int i, j;
  3064. {
  3065.     removeStones0( b, pris, i, j, b[i][j] );
  3066. }
  3067.  
  3068. boolean tryKill( b, pris, i, j, t )
  3069.     boardtype b;
  3070.     int *pris;
  3071.     int i, j;
  3072.     piece t;
  3073. {
  3074.     piece w;
  3075.  
  3076.     if (!inRange(i, j)) return false;
  3077.     w = b[i][j];
  3078.     if (w != EMPTY && w != t && !alive(b, i, j)) {
  3079.         removeStones(b, pris, i, j);
  3080.         return true;
  3081.     }
  3082.     else return false;
  3083. }
  3084.  
  3085. boolean placeStone( b, pris, i, j, t )
  3086.     boardtype b;
  3087.     int *pris;
  3088.     int i, j;
  3089.     piece t;
  3090. {
  3091.     boolean ret = FALSE;
  3092.  
  3093.     if (inRange(i, j)) {
  3094.         b[i][j] = t;
  3095.         if (j) ret = tryKill(b, pris, i, j - 1, t);
  3096.         if (j < boardsize - 1) ret |= tryKill(b, pris, i, j + 1, t);
  3097.         if (i) ret |= tryKill(b, pris, i - 1, j, t);
  3098.         if (i < boardsize - 1) ret |= tryKill(b, pris, i + 1, j, t);
  3099.     }
  3100.     return( ret );
  3101. }
  3102.  
  3103. /* return the info on move "num"  (real move) */
  3104. getmove( num, x, y, f )
  3105.     int num;
  3106.     int *x, *y, *f;
  3107. {
  3108.     *x = realmovelist[num].x+1;
  3109.     *y = realmovelist[num].y+1;
  3110.     *f = (int)realmovelist[num].flag;
  3111.     return( num );
  3112. }
  3113.  
  3114. /* delete the move "num" from the movetable */
  3115. removemove( num, type )
  3116.     int num, type;
  3117. {
  3118.     int x, y;
  3119.  
  3120.     if( type == REALMOVE ) {
  3121.         x = realmovelist[num].x;
  3122.         y = realmovelist[num].y;
  3123.         board[x][y] = EMPTY;
  3124.         realmovelist[num].x = 0;
  3125.         realmovelist[num].y = 0;
  3126.         realmovelist[num].flag = FALSE;
  3127.     }
  3128.     else if( type == STEPMOVE ) {
  3129.         x = stepmovelist[num].x;
  3130.         y = stepmovelist[num].y;
  3131.         stepboard[x][y] = EMPTY;
  3132.         stepmovelist[num].x = 0;
  3133.         stepmovelist[num].y = 0;
  3134.         stepmovelist[num].flag = FALSE;
  3135.     }
  3136. }
  3137.  
  3138. makemove( i, j, num, t, type )
  3139.     int i, j, num;
  3140.     piece t;
  3141.     int type;    /* update REALMOVE, STEPMOVE data? */
  3142. {
  3143.     int x, y, flag;
  3144.  
  3145.     tt = type;
  3146.  
  3147.     --i;
  3148.     --j;
  3149.     if( i < (-1) ) {        /* pass */
  3150.         if( type == REALMOVE ) {
  3151.             realmovelist[num].x = i;
  3152.             realmovelist[num].y = j;
  3153.             realmovelist[num].flag = FALSE;
  3154.         }
  3155.         if( type == STEPMOVE ) {
  3156.             stepmovelist[num].x = i;
  3157.             stepmovelist[num].y = j;
  3158.             stepmovelist[num].flag = FALSE;
  3159.         }
  3160.     }
  3161.     else {                /* place stone */
  3162.         if( type == REALMOVE ) {
  3163.             realmovelist[num].x = i;
  3164.             realmovelist[num].y = j;
  3165.             realmovelist[num].flag = placeStone( board, prisoners,
  3166.                             i, j, t );
  3167.         }
  3168.         if( type == STEPMOVE ||
  3169.         (type == REALMOVE && (!boardchanged && !mouseflag)) ) {
  3170.             stepmovelist[num].x = i;
  3171.             stepmovelist[num].y = j;
  3172.             stepmovelist[num].flag = placeStone( stepboard,
  3173.                     stepprisoners, i, j, t );
  3174.         }
  3175.         if( type == REALMOVE ) {
  3176.         if( !boardchanged && !mouseflag ) drawStone( i+1, j+1, t, TRUE);
  3177.             else beep();
  3178.         }
  3179.         if( type == STEPMOVE && (boardchanged || mouseflag) )
  3180.         drawStone( i+1, j+1, t, TRUE );
  3181.     }
  3182. }
  3183.  
  3184. static int verts[3][26] = {
  3185.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  3186.     2, 0, 0, 0, 3, 0, 0, 0, 0, 0,  3, 0,  3, 0, 0, 0, 4},
  3187.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  3188.     4, 0, 0, 0, 6, 0, 0, 0, 0, 0,  9, 0, 10, 0, 0, 0, 12},
  3189.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 
  3190.     6, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 17, 0, 0, 0, 20},
  3191. };
  3192.  
  3193. /*
  3194.  * Set the handicap of "hand" stones on the board....
  3195.  * use "verts" table above....
  3196.  */
  3197. sethandicap( hand, type )
  3198.     int hand;
  3199.     int type;
  3200. {
  3201.     int top, mid, bot;
  3202.     piece t;
  3203.  
  3204.     top = verts[TOP][boardsize] +1;
  3205.     mid = verts[MID][boardsize] +1;
  3206.     bot = verts[BOT][boardsize] +1;
  3207.  
  3208.     /* 
  3209.      * All of these drop through, '5' checks for odd points.
  3210.      */
  3211.     t=1;
  3212.     switch (hand) {
  3213.         case 9:         /* taken care of by handi == 5 */
  3214.         case 8: 
  3215.         makemove( mid, top, 0, t, type );
  3216.         makemove( mid, bot, 0, t, type );
  3217.         case 7:         /* taken care of by handi == 5 */
  3218.         case 6: 
  3219.         makemove( bot, mid, 0, t, type );
  3220.         makemove( top, mid, 0, t, type );
  3221.         case 5: 
  3222.         /* odd points, test because of drop through */
  3223.         if (hand & 0x1) {
  3224.             makemove( mid, mid, 0, t, type );
  3225.         }
  3226.         case 4: 
  3227.         makemove( bot, top, 0, t, type );
  3228.         case 3: 
  3229.         makemove( top, bot, 0, t, type );
  3230.         case 2: 
  3231.         makemove( bot, bot, 0, t, type );
  3232.         makemove( top, top, 0, t, type );
  3233.         break;
  3234.         default: 
  3235.         break;
  3236.     }
  3237. }
  3238.  
  3239. sgf_hcap( f, s, h )
  3240.     FILE *f;
  3241.     int s, h;
  3242. {
  3243.     char *ss = NULL;
  3244.  
  3245.     switch( s ) {
  3246.         case 19:
  3247.         switch( h ) {
  3248.             case 2:
  3249.             ss = "AddBlack[dp][pd]";
  3250.             break;
  3251.             case 3:
  3252.             ss = "AddBlack[dp][pd][dd]";
  3253.             break;
  3254.             case 4:
  3255.             ss = "AddBlack[dd][dp][pd][pp]";
  3256.             break;
  3257.             case 5:
  3258.             ss = "AddBlack[dd][dp][jj][pd][pp]";
  3259.             break;
  3260.             case 6:
  3261.             ss = "AddBlack[dd][dj][dp][pd][pj][pp]";
  3262.             break;
  3263.             case 7:
  3264.             ss = "AddBlack[dd][dj][dp][jj][pd][pj][pp]";
  3265.             break;
  3266.             case 8:
  3267.             ss = "AddBlack[dd][dj][dp][jd][jp][pd][pj][pp]";
  3268.             break;
  3269.             case 9:
  3270.             ss = "AddBlack[dd][dj][dp][jd][jj][jp][pd][pj][pp]";
  3271.             break;
  3272.             default:
  3273.             break;
  3274.         }
  3275.         break;
  3276.         case 13:
  3277.         switch( h ) {
  3278.             case 2:
  3279.             ss = "AddBlack[dj][jd]";
  3280.             break;
  3281.             case 3:
  3282.             ss = "AddBlack[dj][jd][dd]";
  3283.             break;
  3284.             case 4:
  3285.             ss = "AddBlack[dd][dj][jd][jj]";
  3286.             break;
  3287.             case 5:
  3288.             ss = "AddBlack[dd][dj][gg][jd][jj]";
  3289.             break;
  3290.             default:
  3291.             break;
  3292.         }
  3293.         break;
  3294.         case 9:
  3295.         switch( h ) {
  3296.             case 2:
  3297.             ss = "AddBlack[cg][gc]";
  3298.             break;
  3299.             case 3:
  3300.             ss = "AddBlack[cg][gc][cc]";
  3301.             break;
  3302.             case 4:
  3303.             ss = "AddBlack[cc][cg][gc][gg]";
  3304.             break;
  3305.             default:
  3306.             break;
  3307.         }
  3308.         break;
  3309.         default:
  3310.         break;
  3311.     }
  3312.  
  3313.     if( ss != NULL ) fprintf( f, ";\n%s\n", ss );
  3314. }
  3315. SHAR_EOF
  3316. fi
  3317. if test -f 'filter.c'
  3318. then
  3319.     echo shar: "will not over-write existing file 'filter.c'"
  3320. else
  3321. cat << \SHAR_EOF > 'filter.c'
  3322. /* filter.c
  3323.  * S.Coffin    USWAT 1/93
  3324.  *
  3325.  * process I/O stream between user and igs
  3326.  */
  3327.  
  3328. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  3329.  *
  3330.  *  This program is distributed in the hope that it will be useful.
  3331.  *  Use and copying of this software and preparation of derivative works
  3332.  *  based upon this software are permitted, so long as the following
  3333.  *  conditions are met:
  3334.  *       o credit to the authors is acknowledged following current
  3335.  *         academic behavior
  3336.  *       o no fees or compensation are charged for use, copies, or
  3337.  *         access to this software
  3338.  *       o this copyright notice is included intact.
  3339.  *  This software is made available AS IS, and no warranty is made about 
  3340.  *  the software or its performance. 
  3341.  * 
  3342.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  3343.  *  Send them to    scoffin@uswest.com
  3344.  */
  3345.  
  3346. #include "filter.h"
  3347. #include "shared.h"
  3348. #include <signal.h>
  3349.  
  3350. static char kbd_str[LINESIZE];
  3351. char observeflag = FALSE;
  3352. static char infileflag = FALSE;
  3353. int move = (-1);
  3354. int stepmove = (-1);
  3355. extern int currentmove;
  3356. static char undoflag = FALSE;
  3357.  
  3358. extern int gameno, handicap;
  3359. extern int boardsize;
  3360. extern char player1[], player2[];
  3361. char splayer1[20], splayer2[20];
  3362. extern int p1_sec, p2_sec;
  3363. extern int p1_captured, p2_captured;
  3364. extern int p1_byoyomi, p2_byoyomi;
  3365. int sp1_sec, sp2_sec;
  3366. int sp1_captured, sp2_captured;
  3367. int sp1_byoyomi, sp2_byoyomi;
  3368. float sp1_komi;
  3369. int sp1_hcap;
  3370. int sgameno;
  3371. extern int colorflag;
  3372. extern int set_cursor_color();
  3373. extern int boardchanged, mouseflag;
  3374. extern unsigned char statusflag;
  3375.  
  3376. extern int dbg;
  3377. extern void catcher();
  3378. extern void score_it();
  3379. extern void setMark();
  3380. extern void do_refresh(), RefreshHost();
  3381. extern void clearit();
  3382. char *SCstrstr();
  3383.  
  3384. int setup_filter(exec_stdin, exec_stdout, exec_stderr )
  3385.     FILE **exec_stdin, **exec_stdout, **exec_stderr;
  3386. {
  3387.     char delim = ' ';
  3388.     int i, tpid;
  3389.     extern char cmdline[];
  3390.  
  3391.     /* handle signals carefully */
  3392.     for( i = 1; i <= SIGUSR2; ++i ) signal( i, catcher );
  3393.     signal( SIGWINCH, SIG_IGN );
  3394.     signal( SIGINT, SIG_IGN );
  3395.     signal( SIGQUIT, SIG_IGN );
  3396.  
  3397.     /* and exec, using FILE's for i/o  */
  3398.     tpid = rdwr_popen( exec_stdout, exec_stdin, exec_stderr, cmdline,
  3399.         NULL, delim );
  3400.  
  3401.     if( tpid < 0 ) {
  3402.         fprintf( stderr, "FORK FAILED!\n" );
  3403.         return( (-1) );
  3404.     }
  3405.     else if( dbg ) fprintf( stderr, "Fork succeeds; pid=%d\n", tpid );
  3406.  
  3407.     return( tpid );
  3408. }
  3409.  
  3410.  
  3411. /* this one parses input of interest from the comm channel, and
  3412.  * takes appropriate action to place stones on the board
  3413.  */
  3414.  
  3415. process_input( str )
  3416.     char *str;
  3417. {
  3418.     int i, j, len, ret, tt, t, c2, c4;
  3419.     float c3;
  3420.     int m, code, yloc;
  3421.     char xloc, color, tflag;
  3422.     static char s[LINESIZE];
  3423.     static int beenhere = FALSE;
  3424.     char *temp_str, *current_str;
  3425.     char p1[20], p2[20], r1[20];
  3426.     int x;
  3427.  
  3428.     if( !beenhere ) {
  3429.         beenhere = TRUE;
  3430.         for( j=0; j<LINESIZE; ++j ) s[j] = '\0';
  3431.     }
  3432.  
  3433.     if( dbg ) fprintf( stderr, "In process_input: str=>>%s<<\n", str );
  3434.  
  3435.     for( temp_str = str ;; ) {
  3436.  
  3437.         /* find newline */
  3438.         for( i=0; temp_str[i] != '\n' && temp_str[i] != '\0'; ++i );
  3439.  
  3440.         /* no newline..... */
  3441.         if( temp_str[i] == '\0' ) {
  3442.         if( i > 0 ) {
  3443.             strcat( s, temp_str );
  3444.         }
  3445.  
  3446.         /* get code */
  3447.         ret = sscanf( s, "%d", &code );
  3448.  
  3449.          /* no code, print it */
  3450.         if(  ret != 1 ) {
  3451.             fprintf( stderr, "%s", s );
  3452.             fflush( stderr );
  3453.             for( j=0; j<LINESIZE; ++j ) s[j] = '\0';
  3454.         }
  3455.         return( 0 );
  3456.         }
  3457.  
  3458.         if( temp_str[i] == '\n' ) {
  3459.  
  3460.         len = strlen(s);
  3461.         strncat( s, temp_str, i );
  3462.         s[i+len+1] = '\0';
  3463.  
  3464.         /* get code */
  3465.         ret = sscanf( s, "%d", &code );
  3466.  
  3467.         /* no code, print it */
  3468.         if( ret != 1 ) {
  3469.                 fprintf( stderr, "%s\n", s );
  3470.                 fflush( stderr );
  3471.         }
  3472.  
  3473.         else {
  3474.             /* find space */
  3475.             for(j=0; s[j] != ' ' && s[j] != '\n' && s[j] != '\r'; ++j );
  3476.             if( s[j] == ' ' ) current_str = &s[++j];
  3477.             else if( s[j] == '\n' || s[j] == '\r' ) current_str = &s[j];
  3478.             else current_str = s;
  3479.  
  3480.             switch( code ) {
  3481.             case HELP:    /* has a "File" after code */
  3482.             case THIST:
  3483.             case STORED:
  3484.             case INFO:
  3485.             case MESSAGE:
  3486.                 /* scoring done under "INFO" msg */
  3487.                 if( observeflag == SCORING ) {
  3488.                 ret = sscanf( current_str, "Removing @ %c%d",
  3489.                         &xloc, &yloc );
  3490.                 if( ret == 2 ) {
  3491.                         xloc = xloc - 'A' + 1;
  3492.                         if( xloc > 8 ) --xloc;
  3493.                     score_it( xloc, yloc );
  3494.                     get_prisoners( &p1_captured, &p2_captured );
  3495.                     if( !statusflag )
  3496.                     update_status( gameno, player2,
  3497.                         player1, p2_captured, p1_captured,
  3498.                         p2_sec, p1_sec, p2_byoyomi,
  3499.                         p1_byoyomi );
  3500.                 }
  3501.                 }
  3502.                 if( strncmp( current_str, "File", 4 ) == 0 ) {
  3503.                 fprintf( stderr, "%s\n", ¤t_str[4] );
  3504.                 if( infileflag ) infileflag = FALSE;
  3505.                 else infileflag = TRUE;
  3506.                 }
  3507.                 else fprintf( stderr, "%s\n", current_str );
  3508.                 fflush( stderr );
  3509.                 break;
  3510.             case UNDO:    /* undo */
  3511.                 fprintf( stderr, "\n%s\n", current_str );
  3512.                 fflush( stderr );
  3513.                 move = undo( move );
  3514.                 break;
  3515.                 case MOVE:    /* a move */
  3516.                 /* game number? */
  3517.                 ret = sscanf( current_str,
  3518.                     "Game %d: %s (%d %d %d) vs %s (%d %d %d)",
  3519.                     &t, player1, &p1_captured, &p1_sec,
  3520.                     &p1_byoyomi, player2, &p2_captured,
  3521.                     &p2_sec, &p2_byoyomi );
  3522.  
  3523.                 if( ret == 9 ) {
  3524.                 if( t != gameno ) {
  3525.                     gameno = t;
  3526.                     fprintf( stderr,
  3527.                     "LOCAL: Changing game number to %d\n",
  3528.                     gameno );
  3529.                 }
  3530.  
  3531.                 if( !statusflag )
  3532.                     update_status( gameno, player2,
  3533.                     player1, p2_captured, p1_captured,
  3534.                     p2_sec, p1_sec, p2_byoyomi,
  3535.                     p1_byoyomi );
  3536.                 }
  3537.  
  3538.                 /* handicap? */
  3539.                 ret = sscanf( current_str, "%d(%c): Handicap %d", &m,
  3540.                     &color, &tt );
  3541.                 if( ret == 3 ) {
  3542.                 fprintf( stderr, "Handicap %d\n", tt );
  3543.                 move = (-1);
  3544.                 refreshboard();
  3545.                 handicap = tt;
  3546.                 sethandicap( tt, REALMOVE );
  3547.                 update_handicap( handicap );
  3548.                 if( !boardchanged && !mouseflag ) {
  3549.                     set_cursor_color( move+1 );
  3550.                 }
  3551.                 goto done;
  3552.                 }
  3553.  
  3554.                 /* its a move? */
  3555.                         ret = sscanf( current_str, "%d(%c): %c%d",
  3556.                 &m, &color, &xloc, &yloc );
  3557.                     if( ret == 4 ) {
  3558.                 if( stepmove >= move || stepmove == (-1) )
  3559.                         stepmove = m;
  3560.                 if( !boardchanged && !mouseflag )
  3561.                     currentmove = m;
  3562.  
  3563.                 move = m;
  3564.  
  3565.                             if( dbg ) {
  3566.                             fprintf( stderr,
  3567.                             "Move=%d, color=%c, xloc=%c, yloc=%d\n",
  3568.                             move, color, xloc, yloc );
  3569.                         }
  3570.                     ret = xloc - 'A' + 1;
  3571.                     if( ret > 8 ) --ret;
  3572.                 if( !undoflag || observeflag != PLAYING ) {
  3573.                         if( color == 'W' ) {
  3574.                                 makemove(ret, yloc, move,
  3575.                             WHITE, REALMOVE );
  3576.                     }
  3577.                         else if( color == 'B' ) {
  3578.                                 makemove( ret, yloc, move,
  3579.                             BLACK, REALMOVE);
  3580.                     }
  3581.                 }
  3582.                 undoflag = FALSE;
  3583.                 if( !boardchanged && !mouseflag ) {
  3584.                     set_cursor_color( move );
  3585.                 }
  3586.                 update_move( current_str );
  3587.                         fprintf( stderr, "%s\n", current_str );
  3588.                     fflush( stderr );
  3589.                         }
  3590.  
  3591.                 /* its a pass ?? */
  3592.                 else if( SCstrstr( current_str, "Pass" ) != NULL ) {
  3593.                 makemove( (-1), (-1), ++move, EMPTY, REALMOVE );
  3594.                 if( stepmove >= move-1 || stepmove == (-1) )
  3595.                         stepmove = move;
  3596.                 if( !boardchanged && !mouseflag )
  3597.                     currentmove = m;
  3598.                 update_move( current_str );
  3599.                 set_cursor_color( colorflag+1 );
  3600.                         fprintf( stderr, "%s\n", current_str );
  3601.                     fflush( stderr );
  3602.                 }
  3603.                 
  3604.               done:
  3605.                     break;
  3606.             case PROMPT:    /* prompt */
  3607.                 sscanf( current_str, "%d", &c2 );
  3608.                 switch( c2 ) {
  3609.                 case LOGON:
  3610.                     fprintf( stderr, "Login: " );
  3611.                     break;
  3612.                 case PASSWORD:
  3613.                     fprintf( stderr, "Password: " );
  3614.                     break;
  3615.                 case PASSWD_NEW:
  3616.                    fprintf( stderr, "New Password: " );
  3617.                    break;
  3618.                 case PASSWD_CONFIRM:
  3619.                    fprintf( stderr, "Re-enter Password: " );
  3620.                    break;
  3621.                 case WAITING:
  3622.                     fprintf( stderr, "igs> " );
  3623.                     observeflag = FALSE;
  3624.                     break;
  3625.                 case PLAYING:
  3626.                     /* refresh board if just start playing */
  3627.                     if( observeflag != PLAYING )
  3628.                     RefreshHost( NULL, NULL );
  3629.                     fprintf( stderr, "igs [p%d]> ", gameno );
  3630.                     observeflag = PLAYING;
  3631.                     break;
  3632.                 case SCORING:
  3633.                     fprintf( stderr, "Remove dead group> " );
  3634.                     observeflag = SCORING;
  3635.                     break;
  3636.                 case OBSERVING:
  3637.                     fprintf( stderr, "igs [o%d]> ", gameno );
  3638.                     observeflag = OBSERVING;
  3639.                     break;
  3640.                 default:
  3641.                             fprintf( stderr, "%s\n", current_str );
  3642.                     observeflag = FALSE;
  3643.                     break;
  3644.                 }
  3645.                 fflush( stderr );
  3646.                 break;
  3647.             case SHOUT:
  3648.                 /* update game number if needed */
  3649.                     fprintf( stderr, "%s\n", current_str );
  3650.                 fflush( stderr );
  3651.                 break;
  3652.             case LOOK_M:
  3653.             case STATUS:    /* screen refresh of current display */
  3654.                 /* player (w in first line), rank, captured,
  3655.                  * time (sec), byoyomi stones, flag (T if byo),
  3656.                  * komi, hcap
  3657.                  */
  3658.                 ret = sscanf( current_str,
  3659.                     "%s %s %d %d %d %c %f %d",
  3660.                     p1, r1, &t, &tt, &c2, &tflag, &c3, &c4 );
  3661.                 if( ret == 8 ) {
  3662.                 if( tflag == 'F' ) c2 = 0;
  3663.                 if( !statusflag ) {
  3664.                     clearit();
  3665.                     boardchanged = TRUE;
  3666.                     highlight( TRUE );
  3667.                     statusflag = TRUE;
  3668.                     strcpy( splayer1, p1 );
  3669.                     sp1_captured = t;
  3670.                     sp1_sec = tt;
  3671.                     sp1_byoyomi = c2;
  3672.                     sp1_komi = c3;
  3673.                     sp1_hcap = c4;
  3674.                 }
  3675.                 else {
  3676.                     strcpy( splayer2, p1 );
  3677.                     sp2_captured = t;
  3678.                     sp2_sec = tt;
  3679.                     sp2_byoyomi = c2;
  3680.                     set_prisoners( sp2_captured, sp1_captured );
  3681.                         update_status( sgameno, splayer2, splayer1,
  3682.                     sp2_captured, sp1_captured, sp2_sec,
  3683.                     sp1_sec, sp2_byoyomi, sp1_byoyomi );
  3684.                     update_move( NULL );
  3685.                 }
  3686.                 break;
  3687.                 }
  3688.                 else {
  3689.                     ret = sscanf( current_str, "%d: %s\n", &x, p1 );
  3690.                     if( ret == 2 ) parse_line( x, p1 );
  3691.                 }
  3692.                 break;
  3693.             case UNKNOWN:    /* strip the code from these, but */
  3694.             case BOARD:    /* otherwise pass them untouched */
  3695.             case DOWN:
  3696.             case ERROR:
  3697.             case FIL:
  3698.             case GAMES:
  3699.             case LAST:
  3700.             case KIBITZ:
  3701.             case LOAD:
  3702.             case OBSERVE:
  3703.             case REFRESH:
  3704.             case SAVED:
  3705.             case SAY:
  3706.             case SCORE:
  3707.             case TELL:
  3708.             case TRANS:
  3709.             case SHOW:    /* what is this? */
  3710.             case TIM:
  3711.             case WHO:
  3712.                 if( strncmp( current_str, "File", 4 ) == 0 ) {
  3713.                 fprintf( stderr, "%s\n", ¤t_str[4] );
  3714.                 if( infileflag ) infileflag = FALSE;
  3715.                 else infileflag = TRUE;
  3716.                 }
  3717.                 else fprintf( stderr, "%s\n", current_str );
  3718.                 fflush( stderr );
  3719.                     break;
  3720.             case BEEP:
  3721.                 if( current_str[0] == 0x07 ) {
  3722.                 fprintf( stderr, "\007\n" );
  3723.                     fflush( stderr );
  3724.                 break;
  3725.                 }
  3726.                 if( current_str[0] == '2' ) {
  3727.                 fprintf( stderr, "\007" );
  3728.                 current_str += 2;
  3729.                 }
  3730.                 fprintf( stderr, "%s\n", current_str );
  3731.                 fflush( stderr );
  3732.                 break;
  3733.             default:    /* print code if it is unexpected */
  3734.                     fprintf( stderr, "%d %s\n", code, current_str );
  3735.                 fflush( stderr );
  3736.                     break;
  3737.             }
  3738.         }
  3739.             
  3740.         /* reset active string */
  3741.         for( j=0; j<LINESIZE; ++j ) s[j] = '\0';
  3742.         temp_str = &temp_str[i+1];
  3743.         continue;
  3744.         }
  3745.     }
  3746. }
  3747.  
  3748. /* examine user input from keyboard for commands of local interest
  3749.  *
  3750.  * return 0 = don't send original string to host
  3751.  * return 1 = send original string to host
  3752.  */
  3753. process_kbd( str, fp )
  3754.     char *str;
  3755.     FILE *fp;
  3756. {
  3757.     int i, t, ret;
  3758.     char s[40];
  3759.  
  3760.     if( dbg ) fprintf( stderr, "In process_kbd:  >>%s<<", str );
  3761.  
  3762.     for( i=0; str[i] != '\0'; ++i ) kbd_str[i] = tolower( str[i] );
  3763.     kbd_str[i] = '\0';
  3764.  
  3765.     if( strncmp( kbd_str, "gameno", 6 ) == 0 ) {
  3766.         sscanf( kbd_str, "gameno %d", &gameno );
  3767.         fprintf( stderr, "LOCAL:  Set game number to %d\n", gameno );
  3768.         fflush( stderr );
  3769.             fprintf( fp, "\n" );
  3770.             fflush( fp );
  3771.         return( 0 );
  3772.     }
  3773.     if( strncmp( kbd_str, "load ", 5 ) == 0 ) {
  3774.         if( observeflag == SCORING || observeflag == PLAYING ) {
  3775.         fprintf( stderr, "LOCAL: cannot load while playing\n" );
  3776.             fprintf( fp, "\n" );
  3777.             fflush( fp );
  3778.         return( 0 );
  3779.         }
  3780.         if( observeflag == OBSERVING ) {
  3781.         fprintf( stderr, "LOCAL: cannot load while observing;\n" );
  3782.         fprintf( stderr, "Use \"observeoff\" to stop observing\n" );
  3783.             fprintf( fp, "\n" );
  3784.             fflush( fp );
  3785.         return( 0 );
  3786.         }
  3787.         else {
  3788.             return( 1 );
  3789.         }
  3790.     }
  3791.     if( strncmp( kbd_str, "look ", 5 ) == 0 ) {
  3792.         if( observeflag == SCORING ) {
  3793.         fprintf( stderr, "LOCAL: cannot look while scoring\n" );
  3794.             fprintf( fp, "\n" );
  3795.             fflush( fp );
  3796.         return( 0 );
  3797.         }
  3798.         else {
  3799.             statusflag = FALSE;
  3800.             return( 1 );
  3801.         }
  3802.     }
  3803.     if( strncmp( kbd_str, "status ", 7 ) == 0 ) {
  3804.         if( observeflag == SCORING ) {
  3805.         fprintf( stderr, "LOCAL: cannot get status while scoring\n" );
  3806.             fprintf( fp, "\n" );
  3807.             fflush( fp );
  3808.         return( 0 );
  3809.         }
  3810.         else {
  3811.             sscanf( kbd_str, "status %d", &sgameno );
  3812.             statusflag = FALSE;
  3813.             return( 1 );
  3814.         }
  3815.     }
  3816.     else if( (strncmp( kbd_str, "moves", 4 ) == 0 && kbd_str[5] != ' ' ) ||
  3817.          (strncmp( kbd_str, "refresh", 7 ) == 0 && kbd_str[7] != ' ') ) {
  3818.         if( gameno < 0 ) {
  3819.         fprintf( stderr, "LOCAL: no current game to refresh\n" );
  3820.         fflush( stderr );
  3821.             fprintf( fp, "\n" );
  3822.             fflush( fp );
  3823.         }
  3824.         else {
  3825.             move = stepmove = (-1);
  3826.         currentmove = (-1);
  3827.             refreshboard();
  3828.             fprintf( fp, "moves %d\n", gameno );
  3829.             fflush( fp );
  3830.         }
  3831.         return( 0 );
  3832.     }
  3833.     else if( (strncmp( kbd_str, "moves", 4 ) == 0 && kbd_str[5] == ' ' ) ) {
  3834.         sscanf( kbd_str, "moves %d", &ret );
  3835.         if( observeflag && ret != gameno ) {
  3836.             fprintf( stderr,
  3837.             "LOCAL: Can't get moves of another game while observing or playing;\n" );
  3838.             fprintf( stderr, "Use \"status\" instead\n" );
  3839.             fflush( stderr );
  3840.                 fprintf( fp, "\n" );
  3841.                 fflush( fp );
  3842.             return( 0 );
  3843.         }
  3844.         else {
  3845.                 move = stepmove = (-1);
  3846.             currentmove = (-1);
  3847.                 refreshboard();
  3848.             return( 1 );
  3849.         }
  3850.     }
  3851.     else if( strncmp( kbd_str, "refresh ", 8 ) == 0 ) {
  3852.             move = stepmove = (-1);
  3853.         currentmove = (-1);
  3854.         sscanf( kbd_str, "refresh %d", &t );
  3855.             refreshboard();
  3856.             fprintf( fp, "moves %d\n", t );
  3857.             fflush( fp );
  3858.         return( 0 );
  3859.     }
  3860.     else if( strncmp( kbd_str, "observe ", 8 ) == 0 ) {
  3861.         if( observeflag != FALSE ) {
  3862.         fprintf( stderr, "LOCAL: Already observing game %d;", gameno );
  3863.         fprintf( stderr, " can't observe multiple games!\n" );
  3864.         fprintf( stderr, "Use \"observeoff\" to stop observing\n" );
  3865.         fprintf( stderr, "or \"status n\" to see the current position of another game\n" );
  3866.         fflush( stderr );
  3867.             fprintf( fp, "\n" );
  3868.             fflush( fp );
  3869.         return( 0 );
  3870.         }
  3871.         sscanf( kbd_str, "observe %d", &t );
  3872.         gameno = t;
  3873.         move = (-1);
  3874.         refreshboard();
  3875.         fprintf( fp, "observe %d\n", gameno );
  3876.         fflush( fp );
  3877.         sleep( 1 );
  3878.         fprintf( fp, "moves %d\n", gameno );
  3879.         fflush( fp );
  3880.         return( 0 );
  3881.     }
  3882.     else if( strncmp( kbd_str, "observeoff", 10 ) == 0 ) {
  3883.         if( observeflag == FALSE ) {
  3884.         fprintf( stderr, "LOCAL: Not currenty observing\n" );
  3885.         fflush( stderr );
  3886.             fprintf( fp, "\n" );
  3887.             fflush( fp );
  3888.         return( 0 );
  3889.         }
  3890.         fprintf( fp, "observe %d\n", gameno );
  3891.         fflush( fp );
  3892.         return( 0 );
  3893.     }
  3894.     else if( strncmp( kbd_str, "time", 4 ) == 0 && kbd_str[4] != ' ' ) {
  3895.         if( observeflag ) {
  3896.         fprintf( fp, "time %d\n", gameno );
  3897.         fflush( fp );
  3898.         return( 0 );
  3899.         }
  3900.     }
  3901.     else if( strncmp( kbd_str, "all", 3 ) == 0 && kbd_str[3] != ' ' ) {
  3902.         if( observeflag ) {
  3903.         fprintf( fp, "all %d\n", gameno );
  3904.         fflush( fp );
  3905.         return( 0 );
  3906.         }
  3907.     }
  3908.     else if( strncmp( kbd_str, "match", 5 ) == 0 ) {
  3909.         if( observeflag == OBSERVING ) {
  3910.             fprintf( fp, "observe %d\n", gameno );
  3911.             fflush( fp );
  3912.         }
  3913.         else if( observeflag != FALSE ) {
  3914.         fprintf( stderr, "LOCAL: Already playing!\n" );
  3915.         fflush( stderr );
  3916.             fprintf( fp, "\n" );
  3917.             fflush( fp );
  3918.         return( 0 );
  3919.         }
  3920.     }
  3921.  
  3922.     return( 1 );
  3923. }
  3924.  
  3925. /* signal handler to clean up on disasters */
  3926. void catcher( sig, code )
  3927.     int sig, code;
  3928. {
  3929.     extern void rdwr_pclose();
  3930.  
  3931.     if( dbg ) fprintf( stderr, "Signal catcher [sig=%d code=%d]\n",
  3932.             sig, code );
  3933.  
  3934.     rdwr_pclose( NULL, NULL, NULL );
  3935.     exit( code );
  3936. }
  3937.  
  3938. int undo( m )
  3939.     int m;
  3940. {
  3941.     int ret, yloc, flag;
  3942.     char s[40];
  3943.     int x, y;
  3944.  
  3945.     getmove( m, &x, &y, &flag );
  3946.     ret = x;
  3947.     yloc = y;
  3948.  
  3949.     if( ret > 8 ) ++ret;
  3950.     ret += 'A' - 1;
  3951.     sprintf( s, "UNDO: move %d, %c%d", m, (char)ret, yloc );
  3952.     removemove( m, REALMOVE );
  3953.     if( !boardchanged && !mouseflag ) {
  3954.         if( flag ) do_refresh( move-1, NULL, REALMOVE );
  3955.         else {
  3956.         drawStone( x, y, EMPTY, TRUE );
  3957.             getmove( m-1, &ret, &yloc, &flag );
  3958.             drawStone( ret, yloc, ((m-1)%2)+1, TRUE );
  3959.         }
  3960.         set_cursor_color( move-1 );
  3961.     }
  3962.  
  3963.     update_move( s );
  3964.     if( stepmove >= m || stepmove == (-1) ) stepmove = currentmove = m - 1;
  3965.     undoflag = TRUE;
  3966.     return( m - 1 );
  3967. }
  3968.  
  3969. /* Find the first occurrence of s2 in s1  */
  3970. char *SCstrstr( s1, s2 )
  3971.     char *s1, *s2;
  3972. {
  3973.     char c, sc;
  3974.     int len;
  3975.  
  3976.     if( (c = *s2++) != 0 ) {
  3977.         len = strlen(s2);
  3978.         do {
  3979.         do {
  3980.             if ((sc = *s1++) == 0) return (NULL);
  3981.         } while (sc != c);
  3982.         } while (strncmp(s1, s2, len) != 0);
  3983.         s1--;
  3984.     }
  3985.     return( s1 );
  3986. }
  3987.  
  3988. parse_line( line, str )
  3989.     int line;
  3990.     char *str;
  3991. {
  3992.     int xloc, yloc;
  3993.     int len;
  3994.     int i;
  3995.     char c;
  3996.  
  3997.     len = strlen( str );
  3998.     while( str[len-1] == '\n' || str[len-1] == '\r' ) --len;
  3999.     str[len] == '\0';
  4000.  
  4001.     if( dbg )
  4002.         fprintf( stderr, "In parse_line:  line=%d, str=>>%s<<\n",
  4003.                     line, str );
  4004.  
  4005.     xloc = line + 1;
  4006.  
  4007.     for( i = 0; i < len; ++i ) {
  4008.         yloc = len - i;
  4009.         switch( str[i] ) {
  4010.         case '0':        /* black stone */
  4011.             drawStone( xloc, yloc, BLACK, FALSE );
  4012.             break;
  4013.         case '1':        /* white stone */
  4014.             drawStone( xloc, yloc, WHITE, FALSE );
  4015.             break;
  4016.         case '4':        /* White territory */
  4017.             setMark( xloc, yloc, 'w' );
  4018.             update_prisoners( 0, 1 );
  4019.             break;
  4020.         case '5':        /* black territory */
  4021.             setMark( xloc, yloc, 'b' );
  4022.             update_prisoners( 1, 0 );
  4023.             break;
  4024.         case '2':        /* empty point */
  4025.         case '3':        /* dame */
  4026.         case '6':        /* starpoint */
  4027.         case '7':        /* counted */
  4028.             break;
  4029.         case '8':
  4030.         case '9':
  4031.         default:
  4032.             fprintf( stderr,
  4033.             "ERROR IN PARSE_LINE: bad code = 0x%x\n", str[i] );
  4034.             break;
  4035.         }
  4036.     }
  4037.     if( xloc >= len ) {
  4038.         get_prisoners( &sp2_captured, &sp1_captured );
  4039.         /*XXX  include komi in final point count at game end  ?? */
  4040.         update_status( sgameno, splayer2, splayer1, sp2_captured,
  4041.                 sp1_captured, sp2_sec, sp1_sec, sp2_byoyomi,
  4042.                 sp1_byoyomi );
  4043.         update_handicap( sp1_hcap );
  4044.     }
  4045. }
  4046. SHAR_EOF
  4047. fi
  4048. if test -f 'filter.h'
  4049. then
  4050.     echo shar: "will not over-write existing file 'filter.h'"
  4051. else
  4052. cat << \SHAR_EOF > 'filter.h'
  4053. /* filter.h
  4054.  * S.Coffin    USWAT   1/93
  4055.  *
  4056.  * process I/O stream between user and igs
  4057.  */
  4058.  
  4059. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  4060.  *
  4061.  *  This program is distributed in the hope that it will be useful.
  4062.  *  Use and copying of this software and preparation of derivative works
  4063.  *  based upon this software are permitted, so long as the following
  4064.  *  conditions are met:
  4065.  *       o credit to the authors is acknowledged following current
  4066.  *         academic behavior
  4067.  *       o no fees or compensation are charged for use, copies, or
  4068.  *         access to this software
  4069.  *       o this copyright notice is included intact.
  4070.  *  This software is made available AS IS, and no warranty is made about 
  4071.  *  the software or its performance. 
  4072.  * 
  4073.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4074.  *  Send them to    scoffin@uswest.com
  4075.  */
  4076.  
  4077. #include <stdio.h>
  4078. #include <fcntl.h>
  4079. #include <ctype.h>
  4080. #include <sys/types.h>
  4081. #include <sys/stat.h>
  4082. #include <sys/param.h>
  4083. #include <sys/socket.h>
  4084. #include <sys/time.h>
  4085. /*SC
  4086. #include <netinet/in.h>
  4087. #include <netdb.h>
  4088. SC*/
  4089. #include <errno.h>
  4090. #include <signal.h>
  4091. #include <string.h>
  4092. #include "patchlevel.h"
  4093.  
  4094. #ifndef TRUE
  4095. #define TRUE 1
  4096. #endif
  4097. #ifndef FALSE
  4098. #define FALSE 0
  4099. #endif
  4100.  
  4101. #define BLACK 1
  4102. #define WHITE 2
  4103. #define EMPTY 0
  4104.  
  4105. #define TIMEOUT 10
  4106. #define LINESIZE    2048
  4107.  
  4108. #define MAXMOVE    550
  4109.  
  4110. extern void exit();
  4111. extern unsigned sleep();
  4112. extern int errno;
  4113. extern int dbg;
  4114.  
  4115. #define TEXT    1
  4116. #define SGF    2
  4117.  
  4118. #define REALMOVE 1
  4119. #define STEPMOVE 2
  4120. SHAR_EOF
  4121. fi
  4122. if test -f 'igscomm.c'
  4123. then
  4124.     echo shar: "will not over-write existing file 'igscomm.c'"
  4125. else
  4126. cat << \SHAR_EOF > 'igscomm.c'
  4127. /* igscomm.c
  4128.  * S.Coffin   USWAT   1/93
  4129.  *
  4130.  * Simple socket-based comm program for calling the igs
  4131.  */
  4132.  
  4133. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  4134.  *
  4135.  *  This program is distributed in the hope that it will be useful.
  4136.  *  Use and copying of this software and preparation of derivative works
  4137.  *  based upon this software are permitted, so long as the following
  4138.  *  conditions are met:
  4139.  *       o credit to the authors is acknowledged following current
  4140.  *         academic behavior
  4141.  *       o no fees or compensation are charged for use, copies, or
  4142.  *         access to this software
  4143.  *       o this copyright notice is included intact.
  4144.  *  This software is made available AS IS, and no warranty is made about 
  4145.  *  the software or its performance. 
  4146.  * 
  4147.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4148.  *  Send them to    scoffin@uswest.com
  4149.  */
  4150.  
  4151. #include "igscomm.h"
  4152.  
  4153. #define USAGE "Usage:  %s [-d] [-?] [-e] [-h host-address] [-p port-number]\n"
  4154.  
  4155. int dbg = FALSE;
  4156. void SCbcopy();
  4157. int port = PORT;
  4158. int echoflag = TRUE;
  4159.  
  4160. main( argc, argv )
  4161.     int argc;
  4162.     char *argv[];
  4163. {
  4164.     int i, j, sd, count, ret;
  4165.     char *r;
  4166.     struct hostent *hp;
  4167.     char *host = HOST;
  4168.     struct sockaddr_in sin;
  4169.     char str[MSG_SIZE+1];
  4170.     fd_set xx;
  4171.     struct timeval timeout;
  4172.     int yy = 32;
  4173.     extern int getopt();
  4174.     extern char *optarg;
  4175.     extern int optind;
  4176.     int c;
  4177. #ifdef BSD
  4178.     struct sgttyb tin, tout;
  4179. #else
  4180.     struct termio tin, tout;
  4181. #endif
  4182.  
  4183.     while( (c=getopt( argc, argv, "?h:p:de" )) != (-1) ) {
  4184.         switch( c ) {
  4185.         case 'd':    /* debug mode */
  4186.             dbg = TRUE;
  4187.             break;
  4188.         case 'e':    /* disable echo */
  4189.             echoflag = FALSE;
  4190.             break;
  4191.         case 'p':    /* socket number */
  4192.             port = atoi( optarg );
  4193.             break;
  4194.         case 'h':    /* host id */
  4195.             host = optarg;
  4196.             break;
  4197.         case '?':
  4198.         default:
  4199.             fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  4200.                 fprintf( stderr, USAGE, argv[0] );
  4201.             exit( (-1) );
  4202.             break;
  4203.         }
  4204.     }
  4205.  
  4206.     if( optind != argc ) {
  4207.         fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  4208.         fprintf( stderr, USAGE, argv[0] );
  4209.         exit( (-1) );
  4210.     }
  4211.  
  4212.     hp = gethostbyname( host );
  4213.     if( hp == NULL ) {
  4214.         fprintf( stderr, "host >>%s<< not found!\n", host );
  4215.         exit( 1 );
  4216.     }
  4217.  
  4218.     if( dbg ) fprintf( stderr, "hp->h_name= >>%s<<\n", hp->h_name );
  4219.     if( hp->h_aliases[0] != NULL ) {
  4220.         if( dbg ) fprintf( stderr, "aliases:\n" );
  4221.         for( i=0; hp->h_aliases[i] != NULL; ++i )
  4222.             if( dbg )
  4223.             fprintf( stderr, "\t%d. >>%s<<\n", i, hp->h_aliases[i] );
  4224.     }
  4225.  
  4226.     /* don't use bzero() or bcopy() since some systems don't have them */
  4227.     for( i=0; i<sizeof(sin); ++i ) *((char *)(&sin + i)) = 0; 
  4228.     SCbcopy( hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length );
  4229.  
  4230.     sin.sin_family = hp->h_addrtype;
  4231.     sin.sin_port = htons( port );
  4232.  
  4233.     if( (sd=socket( hp->h_addrtype, SOCK_STREAM, 0 ) ) < 0 ) {
  4234.         perror( "socket" );
  4235.         exit( 2 );
  4236.     }
  4237.  
  4238.     if( connect( sd, (char *)&sin, sizeof( sin ) ) < 0 ) {
  4239.         perror( "connect" );
  4240.         exit( 3 );
  4241.     }
  4242.  
  4243.     /* connected now */
  4244.  
  4245.     /* turn of echo */
  4246.     /*XXX  I don't know if this code is ok for ALL UNIX versions */
  4247.     if( !echoflag ) {
  4248. #ifdef BSD
  4249.         ioctl( fileno(stdin), TIOCGETP, &tin );
  4250.         tout = tin;
  4251.         tout.sg_flags &= ~ECHO;
  4252.         ioctl( fileno(stdin), TIOCSETP, &tout );
  4253. #else
  4254.         ioctl( fileno(stdin), TCGETA, &tin );
  4255.         tout = tin;
  4256.         tout.c_lflag &= ~ECHO;
  4257.         ioctl( fileno(stdin), TCSETAW, &tout );
  4258. #endif
  4259.     }
  4260.  
  4261.     for( ;; ) {
  4262.         timeout.tv_sec = TIMEOUT;
  4263.         timeout.tv_usec = 0L;
  4264.         FD_ZERO( &xx );
  4265.         FD_SET( sd, &xx );    /* listen on the socket */
  4266.         FD_SET( 0, &xx );    /* listen for kbd input */
  4267.  
  4268.         ret = select( yy, &xx, NULL, NULL, &timeout );
  4269.  
  4270.         /* error ? */
  4271.         if( ret < 0 ) {
  4272.             /* exit on interrupt ?? */
  4273.         if( errno == EINTR ) break;
  4274.  
  4275.             /* any other interruption is an error! */
  4276.         else {
  4277.             perror( "select" );
  4278.             break;
  4279.         }
  4280.         }
  4281.  
  4282.         /* timeout */
  4283.         else if( ret == 0 ) {
  4284.         if( dbg ) fprintf( stderr, "Timeout\n" );
  4285.         continue;
  4286.         }
  4287.  
  4288.         /* input from socket.... print it */
  4289.         else if( FD_ISSET( sd, &xx ) ) {
  4290.         FD_CLR( sd, &xx );
  4291.             if( (count=recv( sd, str, MSG_SIZE, 0 )) < 0 ) {
  4292.             perror( "recv" );
  4293.             break;
  4294.             }
  4295.         if( count == 0 ) {
  4296.             fprintf( stderr, "Connection closed by foreign host.\n" );
  4297.             break;
  4298.         }
  4299.  
  4300.             str[count] = '\0';
  4301.         for( j=0; j < count; ++j ) {
  4302.             if( isascii( str[j] ) &&
  4303.             (isgraph( str[j] ) || isspace( str[j] ) ) ) {
  4304.                 putchar( str[j] );
  4305.             }
  4306.         }
  4307.         fflush( stdout );
  4308.         continue;
  4309.         }
  4310.  
  4311.         /* input from keyboard....  send it */
  4312.         else if( FD_ISSET( 0, &xx ) ) {
  4313.         FD_CLR( 0, &xx );
  4314.             if( (r = gets( str )) == NULL ) break;
  4315.             j = strlen(str);
  4316.             if( str[0] == '.' && j == 1 ) break;
  4317.             str[j++] = '\n';
  4318.             str[j+1] = '\0';
  4319.  
  4320.             /* send a message to the server PORT on HOST */
  4321.             if( send( sd, str, j, 0 ) < 0 ) {
  4322.             perror( "send" );
  4323.             break;
  4324.             }
  4325.         continue;
  4326.         }
  4327.     }
  4328.  
  4329.     /* close the socket connection */
  4330.     if( shutdown( sd, 2 ) < 0 ) {
  4331.         perror( "shutdown" );
  4332.         exit( 1 );
  4333.     }
  4334.  
  4335.     close( sd );
  4336. }
  4337.  
  4338. /* really crude, unsafe version of bcopy() */
  4339. void SCbcopy (b1, b2, length)
  4340.     register char *b1;
  4341.     register char *b2;
  4342.     register unsigned length;
  4343. {
  4344.     while (length-- > 0) *b2++ = *b1++;
  4345. }
  4346. SHAR_EOF
  4347. fi
  4348. if test -f 'igscomm.h'
  4349. then
  4350.     echo shar: "will not over-write existing file 'igscomm.h'"
  4351. else
  4352. cat << \SHAR_EOF > 'igscomm.h'
  4353. /*    igscomm.h
  4354.  *    S.Coffin   USWAT   1/93
  4355.  */
  4356.  
  4357. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  4358.  *
  4359.  *  This program is distributed in the hope that it will be useful.
  4360.  *  Use and copying of this software and preparation of derivative works
  4361.  *  based upon this software are permitted, so long as the following
  4362.  *  conditions are met:
  4363.  *       o credit to the authors is acknowledged following current
  4364.  *         academic behavior
  4365.  *       o no fees or compensation are charged for use, copies, or
  4366.  *         access to this software
  4367.  *       o this copyright notice is included intact.
  4368.  *  This software is made available AS IS, and no warranty is made about 
  4369.  *  the software or its performance. 
  4370.  * 
  4371.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4372.  *  Send them to    scoffin@uswest.com
  4373.  */
  4374.  
  4375. #include <stdio.h>
  4376. #include <fcntl.h>
  4377. #include <ctype.h>
  4378. #include <sys/param.h>
  4379. #include <sys/types.h>
  4380. #include <sys/socket.h>
  4381. #include <sys/time.h>
  4382. #include <netinet/in.h>
  4383. #include <netdb.h>
  4384. #include <errno.h>
  4385. #include <signal.h>
  4386. #include <string.h>
  4387.  
  4388. #ifdef BSD
  4389. #include <sgtty.h>
  4390. #else
  4391. #include <termio.h>
  4392. #endif
  4393.  
  4394. #include "patchlevel.h"
  4395.  
  4396. #ifndef TRUE
  4397. #define TRUE 1
  4398. #endif
  4399. #ifndef FALSE
  4400. #define FALSE 0
  4401. #endif
  4402.  
  4403. extern void exit();
  4404. extern unsigned sleep();
  4405.  
  4406. extern int dbg;
  4407. extern int errno;
  4408.  
  4409. #define TIMEOUT     10    /* seconds to wait between samples */
  4410.  
  4411. #define HOST        "128.32.201.46"
  4412. #define PORT        6969
  4413. #define MSG_SIZE    1024
  4414. SHAR_EOF
  4415. fi
  4416. if test -f 'patchlevel.h'
  4417. then
  4418.     echo shar: "will not over-write existing file 'patchlevel.h'"
  4419. else
  4420. cat << \SHAR_EOF > 'patchlevel.h'
  4421. #define PATCHLEVEL "v2.1"
  4422. SHAR_EOF
  4423. fi
  4424. if test -f 'pipes.c'
  4425. then
  4426.     echo shar: "will not over-write existing file 'pipes.c'"
  4427. else
  4428. cat << \SHAR_EOF > 'pipes.c'
  4429. /*    rdwr_popen.c
  4430.  *    S.Coffin   USWAT  3/91
  4431.  *
  4432.  *    rdwr_popen: like popen, but return 3 FILEs, for in, out & err
  4433.  *    NOTE: you usually want to change the buffering on the returned
  4434.  *    FILEs (after they've been opened), probably via a setbuf( fp, NULL )
  4435.  *
  4436.  *    original for email-II    S.Coffin  7/86
  4437.  */
  4438.  
  4439. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  4440.  *
  4441.  *  This program is distributed in the hope that it will be useful.
  4442.  *  Use and copying of this software and preparation of derivative works
  4443.  *  based upon this software are permitted, so long as the following
  4444.  *  conditions are met:
  4445.  *       o credit to the authors is acknowledged following current
  4446.  *         academic behavior
  4447.  *       o no fees or compensation are charged for use, copies, or
  4448.  *         access to this software
  4449.  *       o this copyright notice is included intact.
  4450.  *  This software is made available AS IS, and no warranty is made about 
  4451.  *  the software or its performance. 
  4452.  * 
  4453.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4454.  *  Send them to    scoffin@uswest.com
  4455.  */
  4456.  
  4457. #include <stdio.h>
  4458. #include "filter.h"
  4459.  
  4460. extern FILE *fdopen();
  4461. extern void exit ();
  4462. extern unsigned sleep ();
  4463. static void my_exec();
  4464.  
  4465. static int pid;
  4466.  
  4467. /* returns the pid we exec'ed or zero on error */
  4468. int rdwr_popen (fr, fw, ferr, cmd, env, envdelim )
  4469.     FILE **fr, **fw, **ferr;
  4470.     char *cmd, *env;
  4471.     char envdelim;
  4472. {
  4473.     int tries = 5;
  4474.     unsigned ZZs = 1;
  4475.     int fda [2], fdb [2], fdc [2];
  4476.     int i;
  4477.     char *e, *t;
  4478.  
  4479.     if( dbg ) fprintf( stderr, "in rdwr_popen  cmd=>>%s<<\n", cmd );
  4480.  
  4481.     /* Get all the pipes we need */
  4482.     if( pipe (fda) || pipe (fdb) || pipe (fdc) ) return( 0 );
  4483.         
  4484.     /* Try & fork 5 times, backing off 1, 2, 4 .. seconds each try */
  4485.     while ((pid = fork ()) < 0) {
  4486.         if (--tries == 0) return( 0 );
  4487.         (void) sleep (ZZs);
  4488.         ZZs <<= 1;
  4489.     }
  4490.     if (pid == 0) {            /* child */
  4491.         /* add the envstr to the real environment */
  4492. /*SC  xigc does not use the env arg; we comment this out since some
  4493.  *SC  systems do not have "putenv()"
  4494.         for( e = env ; e != NULL && e[0] != '\0'; e = ++t ) {
  4495.             t = strchr( e, envdelim );
  4496.             if( t != NULL ) *t = '\0';
  4497.             if( dbg ) {
  4498.             fprintf( stderr, "env=>>%s<<\n", e );
  4499.             fflush( stderr );
  4500.             }
  4501.             putenv( e );
  4502.             if( dbg ) {
  4503.             fprintf( stderr, "PUTENV DONE\n" );
  4504.             fflush( stderr );
  4505.             }
  4506.             if( t == NULL ) break;
  4507.         }
  4508. SC*/
  4509.  
  4510.         if( fda[0] != 0 ) {
  4511.             (void) close( 0 );
  4512.             i = dup (fda [0]);
  4513.             if( i != 0 ) exit( (-1) );
  4514.         }
  4515.         if( fdb[1] != 1 ) {
  4516.             (void)close (1);
  4517.             if (dup (fdb [1]) != 1) exit( (-1) );
  4518.         }
  4519.         if( fdc[1] != 2 ) {
  4520.             (void)close (2);
  4521.             if (dup (fdc [1]) != 2) exit( (-1) );
  4522.         }
  4523.             
  4524.         /* Make sure there are no inherited file descriptors */
  4525.         for (i = 3; i < NOFILE; i += 1) (void) close (i);
  4526.  
  4527.         /* and exec */
  4528.         my_exec( cmd );
  4529.         exit( 0 );
  4530.         /*NOTREACHED*/
  4531.     } else {
  4532.         /* Parent */
  4533.         if (fr && (*fr = fdopen (fdb [0], "r")) == NULL) return( (-1) );
  4534.         if (fw && (*fw = fdopen (fda [1], "w")) == NULL) return( (-1) );
  4535.         if (ferr && (*ferr = fdopen (fdc [0], "r")) == NULL) return( (-1) );
  4536.         (void) close (fdc [1]);
  4537.         (void) close (fdb [1]);
  4538.         (void) close (fda [0]);
  4539.         return( pid );
  4540.     }
  4541. }
  4542.  
  4543. /*ARGSUSED*/
  4544. rdwr_pclose (fin, fout, ferr)
  4545.     FILE *fin, *fout, *ferr;
  4546. {
  4547.     (void) kill (pid, SIGKILL);
  4548.     (void) wait ((int *)0);
  4549. }
  4550.  
  4551. static void my_exec (ccmd)
  4552.     char *ccmd;
  4553. {
  4554.  
  4555. /* Can only be MAXARGS arguments */
  4556. #define MAXARGS    64
  4557.  
  4558.     char *argv [MAXARGS];
  4559.     register char **argv_p, *cp;
  4560.  
  4561.     if( dbg ) {
  4562.         fprintf( stderr, "my_exec  cmd=>>%s<<\n", ccmd );
  4563.         fflush( stderr );
  4564.     }
  4565.     
  4566.     argv_p = argv;
  4567.     cp = ccmd;
  4568.     /* Scan up cmd, splitting arguments into argv. This is the
  4569.      * child, so we can zap things in cmd safely */
  4570.     
  4571.     while (*cp != '\0') {
  4572.         /* Skip any white space */
  4573.         while (*cp && isspace (*cp)) cp += 1;
  4574.         if (*cp == '\0') break;
  4575.         *argv_p++ = cp;
  4576.         while (*cp && !isspace (*cp)) cp += 1;
  4577.         if (*cp == '\0') break;
  4578.         *cp++ = '\0';
  4579.     }
  4580.     *argv_p = NULL;
  4581.     execvp (ccmd, argv);
  4582. }
  4583. SHAR_EOF
  4584. fi
  4585. if test -f 'sample_xigcrc'
  4586. then
  4587.     echo shar: "will not over-write existing file 'sample_xigcrc'"
  4588. else
  4589. cat << \SHAR_EOF > 'sample_xigcrc'
  4590. # this is a sample version of the personal configuration file
  4591. # $HOME/.xigcrc
  4592.  
  4593. COMMAND igscomm -h 128.32.201.46 -p 6969
  4594. QUITCOMMAND .
  4595. # COMMAND telnet 128.32.201.46 6969
  4596. # QUITCOMMAND quit
  4597. SAVEFORMAT sgf
  4598. SHAR_EOF
  4599. fi
  4600. if test -f 'shared.h'
  4601. then
  4602.     echo shar: "will not over-write existing file 'shared.h'"
  4603. else
  4604. cat << \SHAR_EOF > 'shared.h'
  4605. /* shared.h
  4606.  * S.Coffin  USWAT   1/93
  4607.  *
  4608.  * bits for compatibility with the IGS
  4609.  *
  4610.  * adapted from tcasey@leo.unm.edu
  4611.  */
  4612.  
  4613. #ifndef SHARED_H
  4614. #define SHARED_H
  4615.  
  4616. #define MAX_BRD_SZ 25
  4617.  
  4618. typedef enum {
  4619.     UNKNOWN    =  0,
  4620.     BEEP    =  2,     /* \7 telnet         */
  4621.     BOARD    =  3,    /* Board being drawn     */
  4622.     DOWN    =  4,    /* The server is going down */
  4623.     ERROR    =  5,    /* An error reported    */
  4624.           FIL    =  6,    /* File being sent    */
  4625.     GAMES    =  7,    /* Games listing    */
  4626.           HELP    =  8,    /* Help file        */
  4627.     INFO    =  9,    /* Generic info        */
  4628.     LAST    = 10,    /* Last command        */
  4629.           KIBITZ    = 11,    /* Kibitz strings    */
  4630.     LOAD    = 12,    /* Loading a game    */
  4631.     LOOK_M    = 13,    /* Look         */
  4632.           MESSAGE    = 14,    /* Message lising    */
  4633.           MOVE    = 15,    /* Move #:(B) A1    */
  4634.     OBSERVE    = 16,    /* Observe report    */
  4635.           PROMPT    =  1,    /* A Prompt (never)    */
  4636.     REFRESH    = 17,    /* Refresh of a board    */
  4637.           SAVED    = 18,    /* Stored command    */
  4638.           SAY    = 19,    /* Say string        */
  4639.           SCORE    = 20,    /* Score report        */
  4640.           SHOUT    = 21,    /* Shout string        */
  4641.           STATUS    = 22,    /* Current Game status    */
  4642.     STORED    = 23,    /* Stored games        */
  4643.           TELL    = 24,    /* Tell string        */
  4644.     THIST    = 25,    /* Thist report        */
  4645.     TIM    = 26,    /* times command    */
  4646.     WHO    = 27,    /* who command        */
  4647.     UNDO    = 28,    /* Undo report        */
  4648.     SHOW    = 29,
  4649.     TRANS   = 30   /* Translation info     <=== last value */
  4650. } MessageType;
  4651.  
  4652. #define LOGGEDON WAITING
  4653. typedef enum {
  4654.     LOGON        = 0,
  4655.     PASSWORD    = 1,
  4656.     PASSWD_NEW    = 2,
  4657.     PASSWD_CONFIRM    = 3, 
  4658.     REGISTER    = 4, 
  4659.     WAITING        = 5,
  4660.     PLAYING        = 6,
  4661.     SCORING        = 7,
  4662.     OBSERVING    = 8
  4663. } State;
  4664.  
  4665. #define NUM_RANKS num_ranks
  4666. #define NUM_SPECIAL 2
  4667.  
  4668. /*
  4669.  * verticies
  4670.  */
  4671. #define TOP 0
  4672. #define MID 1
  4673. #define BOT 2
  4674.  
  4675. #endif /* SHARED_H */
  4676. SHAR_EOF
  4677. fi
  4678. if test -f 'sound.note'
  4679. then
  4680.     echo shar: "will not over-write existing file 'sound.note'"
  4681. else
  4682. cat << \SHAR_EOF > 'sound.note'
  4683. From cherokee!csn!ub!zaphod.mps.ohio-state.edu!sdd.hp.com!swrinde!gatech!rutgers!network.ucsd.edu!sdcc12!cs!schraudo Mon Aug  3 09:04:34 MDT 1992
  4684. Article: 4285 of rec.games.go
  4685. Path: cherokee!csn!ub!zaphod.mps.ohio-state.edu!sdd.hp.com!swrinde!gatech!rutgers!network.ucsd.edu!sdcc12!cs!schraudo
  4686. From: schraudo@cs.ucsd.edu (Nici Schraudolph)
  4687. Newsgroups: rec.games.go
  4688. Subject: xigs software patch: kinder, gentler sound for Sparcstations
  4689. Message-ID: <36407@sdcc12.ucsd.edu>
  4690. Date: 3 Aug 92 09:27:22 GMT
  4691. Sender: news@sdcc12.ucsd.edu
  4692. Lines: 59
  4693. Nntp-Posting-Host: beowulf.ucsd.edu
  4694.  
  4695.  
  4696. Those of you using xigs on Sun Sparcstations to play on IGS may be
  4697. interested in the following patch.  It replaces the (to me) annoying
  4698. system beep at every move with a high-quality digital recording of a
  4699. slate stone hitting a $10,000 board... well OK, it's a bad recording
  4700. of me rapping on my desk, but still quite an improvement.  Here goes:
  4701.  
  4702. In the xigs source file filter.c, find the place where it says
  4703. "case BEEP:".  Replace the fprintf statement just below that with
  4704. the command "sound(stone);".  At the top of the file, include the
  4705. following, either directly or with a #include directive:
  4706.  
  4707. char stone[] = {
  4708.     0xae, 0xa9, 0x56, 0x2b, 0xcf, 0xa8, 0xba, 0x30, 0x2a, 0x3a,
  4709.     0x38, 0x35, 0x48, 0xbf, 0xa8, 0xab, 0xec, 0x34, 0xcd, 0xaf,
  4710.     0xce, 0x32, 0x26, 0x33, 0xc8, 0xaf, 0xbc, 0x3c, 0x34, 0x43,
  4711.     0x4b, 0x4e, 0xec, 0xe5, 0x44, 0x4f, 0xbf, 0xbe, 0xcc, 0xbf,
  4712.     0xbc, 0x7b, 0x4a, 0xfe, 0xcf, 0xd6, 0x52, 0x34, 0x31, 0x58,
  4713.     0xcf, 0xe0, 0x55, 0xc7, 0xbb, 0xce, 0xd0, 0xb8, 0xb7, 0xe9,
  4714.     0x40, 0x3f, 0x4f, 0xc8, 0xae, 0xad, 0xc6, 0x71, 0xd8, 0xe4,
  4715.     0x4e, 0x4d, 0x4a, 0x34, 0x2d, 0x3d, 0x7b, 0xfe, 0x4e, 0x4d,
  4716.     0x66, 0x61, 0x45, 0x45, 0xd5, 0xe0, 0x3d, 0x47, 0xc8, 0xbd,
  4717.     0xc6, 0xc8, 0xb8, 0xbb, 0x66, 0x4d, 0xdf, 0xca, 0xd1, 0xcf,
  4718.     0xc4, 0xc3, 0x7d, 0x40, 0x4a, 0xe9, 0x61, 0x3c, 0x43, 0xca,
  4719.     0xbb, 0xe6, 0x3d, 0x4d, 0xda, 0x49, 0x37, 0x5f, 0xbd, 0xd3,
  4720.     0x3f, 0x49, 0xcd, 0xc2, 0xc3, 0xcd, 0xeb, 0x74, 0xec, 0xe9,
  4721.     0x7d, 0x79, 0xd8, 0xc5, 0xbe, 0xc4, 0x5c, 0x34, 0x2f, 0x38,
  4722.     0x44, 0x3d, 0x42, 0xdc, 0xc8, 0xd0, 0xc9, 0xb5, 0xaf, 0xbd,
  4723.     0x5a, 0x40, 0x6a, 0xbb, 0xbd, 0x73, 0x45, 0x4b, 0x5c, 0xff,
  4724.     0xc6, 0xbe, 0x66, 0x35, 0x32, 0x36, 0x45, 0xdd, 0xcd, 0xe9,
  4725.     0x4d, 0x49, 0x52, 0xe3, 0xc9, 0xc3, 0xc7, 0xca, 0xc7, 0xbf,
  4726.     0xbd, 0xce, 0x61, 0xf9, 0xe5, 0x5c, 0x3f, 0x3f, 0x51, 0xe8,
  4727.     0xdf, 0x56, 0x48, 0x50, 0x63, 0x56, 0x5a, 0x5f, 0x69, 0xea,
  4728.     0xd0, 0xd7, 0xe0, 0xd6, 0xc9, 0xc8, 0xdb, 0xdf, 0xe2, 0xe9,
  4729.     0xd9, 0xce, 0x7f, 0x3b, 0x37, 0x4a, 0x53, 0x3c, 0x3d, 0x6a,
  4730.     0xc6, 0xb8, 0xb6, 0xc5, 0x5b, 0x41, 0x4a, 0xd0, 0xc4, 0xcf,
  4731.     0xd2, 0xdd, 0x65, 0x5c, 0xd6, 0xc7, 0xd2, 0x55, 0x45, 0x4c,
  4732.     0x72, 0xed, 0x62, 0x5c, 0xea, 0xd9, 0x63, 0x4e, 0x4f, 0x56,
  4733.     0x50, 0x54, 0xe7, 0xd8, 0xf2, 0x00
  4734. };
  4735.  
  4736. sound(s) char *s;
  4737. {
  4738.     FILE *fp;
  4739.  
  4740.     if (fp = fopen("/dev/audio", "w"))
  4741.     {
  4742.         fputs(s, fp);
  4743.         fclose(fp);
  4744.     }
  4745. }
  4746.  
  4747.  
  4748. Enjoy,
  4749. -- 
  4750.   Nicol N. Schraudolph, CSE Dept.  |
  4751.   Univ. of California, San Diego   |
  4752.   La Jolla, CA 92093-0114, U.S.A.  |
  4753.   nici%cs@ucsd.{edu,bitnet,uucp}   |   (this mind intentionally left blank)
  4754.  
  4755.  
  4756. SHAR_EOF
  4757. fi
  4758. if test -f 'stipple.bm'
  4759. then
  4760.     echo shar: "will not over-write existing file 'stipple.bm'"
  4761. else
  4762. cat << \SHAR_EOF > 'stipple.bm'
  4763. /* this is a 50% gray stipple */
  4764.  
  4765. #define stipple_width 2
  4766. #define stipple_height 2
  4767. static unsigned char stipple_bits[] = {
  4768.    0x01, 0x02};
  4769. SHAR_EOF
  4770. fi
  4771. if test -f 'stipple2.bm'
  4772. then
  4773.     echo shar: "will not over-write existing file 'stipple2.bm'"
  4774. else
  4775. cat << \SHAR_EOF > 'stipple2.bm'
  4776. /* This is a 12.5 % gray stipple */
  4777.  
  4778. #define stipple_width 4
  4779. #define stipple_height 4
  4780. static unsigned char stipple_bits[] = {
  4781.    0x0e, 0x0f, 0x0b, 0x0f};
  4782. SHAR_EOF
  4783. fi
  4784. if test -f 'stonemask.bm'
  4785. then
  4786.     echo shar: "will not over-write existing file 'stonemask.bm'"
  4787. else
  4788. cat << \SHAR_EOF > 'stonemask.bm'
  4789. #define stonemask_width 16
  4790. #define stonemask_height 16
  4791. #define stonemask_x_hot 7
  4792. #define stonemask_y_hot 8
  4793. static unsigned char stonemask_bits[] = {
  4794.    0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
  4795.    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x7f,
  4796.    0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
  4797. SHAR_EOF
  4798. fi
  4799. if test -f 'whitestone.bm'
  4800. then
  4801.     echo shar: "will not over-write existing file 'whitestone.bm'"
  4802. else
  4803. cat << \SHAR_EOF > 'whitestone.bm'
  4804. #define whitestone_width 16
  4805. #define whitestone_height 16
  4806. #define whitestone_x_hot 7
  4807. #define whitestone_y_hot 8
  4808. static unsigned char whitestone_bits[] = {
  4809.    0xc0, 0x03, 0x30, 0x0c, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40,
  4810.    0x01, 0x80, 0x01, 0x80, 0x01, 0x90, 0x01, 0x90, 0x02, 0x48, 0x02, 0x44,
  4811.    0x04, 0x23, 0x08, 0x10, 0x30, 0x0c, 0xc0, 0x03};
  4812. SHAR_EOF
  4813. fi
  4814. if test -f 'xigc.c'
  4815. then
  4816.     echo shar: "will not over-write existing file 'xigc.c'"
  4817. else
  4818. cat << \SHAR_EOF > 'xigc.c'
  4819. /* xigc.c
  4820.  * S.Coffin    USWAT    1/93
  4821.  *
  4822.  * Main X11 program for displaying Goban widget, menus, and etc
  4823.  */
  4824.  
  4825. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  4826.  *
  4827.  *  This program is distributed in the hope that it will be useful.
  4828.  *  Use and copying of this software and preparation of derivative works
  4829.  *  based upon this software are permitted, so long as the following
  4830.  *  conditions are met:
  4831.  *       o credit to the authors is acknowledged following current
  4832.  *         academic behavior
  4833.  *       o no fees or compensation are charged for use, copies, or
  4834.  *         access to this software
  4835.  *       o this copyright notice is included intact.
  4836.  *  This software is made available AS IS, and no warranty is made about 
  4837.  *  the software or its performance. 
  4838.  * 
  4839.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  4840.  *  Send them to    scoffin@uswest.com
  4841.  */
  4842.  
  4843. /* uncomment this if you get X error "Attempt to access private resource
  4844.  * failed"  (XGrabKey)   =SC
  4845.  */
  4846. /*SC #define NOKEYGRAB SC*/
  4847.  
  4848. #include <stdio.h>
  4849. #include <X11/Intrinsic.h>
  4850. #include <X11/Shell.h>
  4851. #include <X11/StringDefs.h>
  4852. #include <X11/Xlib.h>
  4853. #include <X11/Xutil.h>
  4854. #include <X11/cursorfont.h>
  4855. #include <X11/Xaw/Command.h>
  4856. #include <X11/Xaw/Form.h>
  4857. #include <X11/Xaw/Box.h>
  4858. #include "filter.h"
  4859. #include "shared.h"
  4860. #include "stipple.bm"
  4861.  
  4862. /* the default communications command to execute */
  4863. #define CMD "igscomm -h 128.32.201.46 -p 6969"
  4864. /* the command to kill the communications proc */
  4865. #define QUITCMD "."
  4866.  
  4867. /* Use of telnet not recommended =SC */
  4868. /* #define CMD "telnet 128.32.201.46 6969" */
  4869. /* #define QUITCMD "\nquit" */
  4870.  
  4871. /* #define CMD "rlogin uswat" */
  4872. /* #define QUITCMD "~." */
  4873.  
  4874. /* #define CMD "cu uswat" */
  4875. /* #define QUITCMD "~." */
  4876.  
  4877. #define USAGE "%s [x-arg-list] [-?] [-c \"command line to execute\"] [-d] [-s]\n"
  4878. #define TITLE "xigc Menu"
  4879. #define ICONTITLE "xigc Menu"
  4880. #define BOARDTITLE "xigc"
  4881. #define BOARDICON "xigc Board"
  4882.  
  4883. char cmdline[80];
  4884. extern int move;
  4885. extern int stepmove;
  4886. int currentmove;
  4887. char stippleflag = FALSE;
  4888. char *cmd[80], *quitcmd[80];
  4889. static void ClearBoard();
  4890.  
  4891. #include "Goban.h"
  4892. void SetCursor ();
  4893. void read_filter(), read_kbd();
  4894. int setup_filter();
  4895. int input0id, input1id, input2id;
  4896. XtAppContext   app_context;
  4897. int dbg = FALSE;
  4898. static int cmdflag = FALSE;
  4899. static int saveformat = (-1);
  4900. static int get_cmd();
  4901. int boardchanged = FALSE;
  4902. int mouseflag = FALSE;
  4903. unsigned char statusflag = FALSE;
  4904.  
  4905.  
  4906. /* these fp's are the std i/o when we EXEC a process */
  4907. FILE *exec_stdin=NULL, *exec_stdout=NULL, *exec_stderr=NULL;
  4908. int gameno=(-1);
  4909. int handicap = 0;
  4910. extern char observeflag;
  4911. int boardsize = 19;
  4912. char player1[20], player2[20];
  4913. int p1_sec, p2_sec;
  4914. int p1_captured, p2_captured;
  4915. int p1_byoyomi, p2_byoyomi;
  4916.  
  4917. Widget toplevel, bw, goban, refresh, clearb, form, size, coordinates;
  4918. Widget stepf, stepb, refreshstep, savecurrent;
  4919. Widget cursorcolor, savegame, localrefresh, quit;
  4920. Widget gamew, hcapw, whitew, blackw, captw, captb, timew, timeb, lastw;
  4921.  
  4922. #define MAXSIZE 19
  4923. int colorflag = BLACK;
  4924.  
  4925. beep() {
  4926.     XBell( XtDisplay(toplevel), 0 );
  4927. }
  4928.  
  4929. highlight( flag )
  4930.     int flag;
  4931. {
  4932.     static int ff = FALSE;
  4933.     int j;
  4934.     Arg args[2];
  4935.     Pixel fg, bg, xx;
  4936.  
  4937.     /* switch highlighting */
  4938.     if( (flag && !ff) || (!flag && ff) ) {
  4939.         j = 0;
  4940.         XtSetArg( args[j], XtNforeground, &fg ); ++j;
  4941.         XtSetArg( args[j], XtNbackground, &bg ); ++j;
  4942.         XtGetValues( localrefresh, args, j );
  4943.         xx = fg;
  4944.         fg = bg;
  4945.         bg = xx;
  4946.         j = 0;
  4947.         XtSetArg( args[j], XtNforeground, fg ); ++j;
  4948.         XtSetArg( args[j], XtNbackground, bg ); ++j;
  4949.         XtSetValues( localrefresh, args, j );
  4950.  
  4951.         ff = flag;
  4952.     }
  4953. }
  4954.  
  4955. clearit() {
  4956.     GbClearBoard( goban );
  4957. }
  4958.  
  4959. static void Quit( w, client_data, call_data )
  4960.     GobanWidget w;
  4961.     XtPointer client_data, call_data;
  4962. {
  4963.     if( cmdflag ) {
  4964.         beep();
  4965.         fprintf( stderr,
  4966.         "\nLOCAL: you must log out of IGS and each intermedate system manually\n" );
  4967.         fprintf( stderr, " when using the \"-c\" option\n" );
  4968.         fprintf( exec_stdin, "\n" );
  4969.         fflush( exec_stdin );
  4970.         return;
  4971.     }
  4972.  
  4973.     fprintf( exec_stdin, "quit\n" );
  4974.     fflush( exec_stdin );
  4975.     sleep( 1 );
  4976.  
  4977.     if( quitcmd[0] == '\0' )
  4978.         fprintf( exec_stdin, "\n%s\n", QUITCMD );
  4979.     else
  4980.         fprintf( exec_stdin, "\n%s\n", quitcmd );
  4981.     fflush( exec_stdin );
  4982.     sleep( 1 );
  4983.     rdwr_pclose (NULL, NULL, NULL );
  4984.     exit( 0 );
  4985. }
  4986.  
  4987. static void SaveGame( w, client_data, call_data )
  4988.     GobanWidget w;
  4989.     XtPointer client_data, call_data;
  4990. {
  4991.     char s[40], s2[40];
  4992.     int ret;
  4993.     struct stat sbuf;
  4994.  
  4995.     if( dbg )
  4996.         fprintf( stderr, "IN SAVEGAME call_data=0x%x\n", client_data );
  4997.  
  4998.     if( (client_data == (XtPointer)REALMOVE && (gameno < 0 || move < 1) ) ||
  4999.         (client_data == (XtPointer)STEPMOVE && currentmove < 0 ) ) {
  5000.         beep();
  5001.         fprintf( stderr, "\nLOCAL:  No active game to save\n" );
  5002.         fflush( stderr );
  5003.     }
  5004.     else {
  5005.         if( (int)strlen( player1 ) <= 0 || (int)strlen( player2 ) <= 0 )
  5006.         strcpy( s, "no_players" );
  5007.         else sprintf( s, "%s-%s", player1, player2 );
  5008.  
  5009.         /* find an unused filename */
  5010.         strcpy( s2, s );
  5011.         for( ret = 1 ;; ++ret ) {
  5012.         if( stat( s2, &sbuf ) == 0 ) {
  5013.             sprintf( s2, "%s.%d", s, ret );
  5014.             continue;
  5015.         }
  5016.         else break;
  5017.         }
  5018.  
  5019.         if( saveformat == SGF )
  5020.             ret = save_game_sgf( s2, player1, player2, handicap,
  5021.                         client_data );
  5022.         else
  5023.             ret = save_game( s2, player1, player2, handicap, client_data );
  5024.         if( ret ) {
  5025.            fprintf( stderr, "\nLOCAL:  Game saved to %s\n", s2 );
  5026.            fflush( stderr );
  5027.         }
  5028.     }
  5029.     fprintf( exec_stdin, "\n" );
  5030.     fflush( exec_stdin );
  5031.     return;
  5032. }
  5033.  
  5034. set_cursor_color( m )
  5035.     int m;
  5036. {
  5037.     if( m % 2 ) {
  5038.         colorflag = BLACK;
  5039.         SetCursor( GbCBlackStone );
  5040.     }
  5041.     else {
  5042.         colorflag = WHITE;
  5043.         SetCursor( GbCWhiteStone );
  5044.     }
  5045.     return( colorflag );
  5046. }
  5047.         
  5048.  
  5049. void do_refresh( m, w, type )
  5050.     int m;
  5051.     Widget w;
  5052.     int type;
  5053. {
  5054.     int i, x, y, flag;
  5055.  
  5056.     GbClearBoard( goban );
  5057.     initboard( boardsize );
  5058.  
  5059.     /* handle handicap */
  5060.     fprintf( stderr, "\n" );
  5061.     if( handicap > 0 ) {
  5062.         sethandicap( handicap, type );
  5063.         update_handicap( handicap );
  5064.         if( w != NULL )
  5065.         fprintf( stderr, "  0 (B):  Handicap %d\n", handicap );
  5066.         i = 1;
  5067.     }
  5068.     else i = 0;
  5069.  
  5070.     for( ; i <= m; ++i ) {
  5071.         getmove( i, &x, &y, &flag );
  5072.         if( i%2 ) {
  5073.         makemove( x, y, i, GbCWhiteStone, type );
  5074.         }
  5075.         else {
  5076.         makemove( x, y, i, GbCBlackStone, type );
  5077.         }
  5078.         if( w != NULL ) {
  5079.         fprintf( stderr, "%3d (%c):  ", i, (i%2) ? 'W' : 'B' );
  5080.         if( x < 0 ) fprintf( stderr, "Pass\n" );
  5081.         else fprintf( stderr, "%c%d\n",
  5082.             'A' + ((x > 8) ? x + 1 : x) - 1, y );
  5083.         }
  5084.     }
  5085.  
  5086.     set_cursor_color( m );
  5087.  
  5088.     fflush( stderr );
  5089.     fprintf( exec_stdin, "\n" );
  5090.     fflush( exec_stdin );
  5091. }
  5092.  
  5093. void RefreshStep( w, client_data, call_data )
  5094.     GobanWidget w;
  5095.     XtPointer client_data, call_data;
  5096. {
  5097.     int i;
  5098.     int x, y;
  5099.  
  5100.     if( move < 0 || gameno < 0 ) {
  5101.         beep();
  5102.         highlight( FALSE );
  5103.         fprintf( stderr, "\nLOCAL:  No active game to refresh\n" );
  5104.         fflush( stderr );
  5105.         fprintf( exec_stdin, "\n" );
  5106.         fflush( exec_stdin );
  5107.         return;
  5108.     }
  5109.     else if( stepmove < 0 || statusflag ) {
  5110.         beep();
  5111.         return;
  5112.     }
  5113.  
  5114.     boardchanged = TRUE;
  5115.     mouseflag = FALSE;
  5116.     do_refresh( stepmove, NULL, STEPMOVE );
  5117.     currentmove = stepmove;
  5118.     if( stepmove >= move ) {
  5119.         boardchanged = FALSE;
  5120.         highlight( FALSE );
  5121.     }
  5122. }
  5123.  
  5124. void LocalRefresh( w, client_data, call_data )
  5125.     GobanWidget w;
  5126.     XtPointer client_data, call_data;
  5127. {
  5128.     int i;
  5129.     int x, y;
  5130.  
  5131.     boardchanged = mouseflag = statusflag = FALSE;
  5132.  
  5133.     if( move < 0 || gameno < 0 ) {
  5134.         beep();
  5135.         highlight( FALSE );
  5136.         fprintf( stderr, "\nLOCAL:  No active game to refresh\n" );
  5137.         fflush( stderr );
  5138.         highlight( FALSE );
  5139.         GbClearBoard( goban );
  5140.         initboard( boardsize );
  5141.         fprintf( exec_stdin, "\n" );
  5142.         fflush( exec_stdin );
  5143.         return;
  5144.     }
  5145.  
  5146. /*SC change "NULL" to "w" to restore print of move list on Refresh(Local) */
  5147.     do_refresh( move, NULL, REALMOVE );
  5148.     stepmove = currentmove = move;
  5149.     highlight( FALSE );
  5150.     update_status( gameno, player2, player1, p2_captured, p1_captured,
  5151.             p2_sec, p1_sec, p2_byoyomi, p1_byoyomi );
  5152.     update_handicap( handicap );
  5153. }
  5154.  
  5155. static char keyecho = TRUE;
  5156.  
  5157. /* This one processes keystrokes when the cursor is in the goban or menu
  5158.  *
  5159.  * adapted from code donated by loganj@byu.edu
  5160.  *
  5161.  * CNTRL-P causes echo to be suppressed until the next newline
  5162.  */
  5163.  
  5164. #ifndef NOKEYGRAB
  5165. static void keyevent( w, client_data, event, continue_flag )     /* BYU */
  5166.     Widget w;
  5167.     XtPointer client_data;
  5168.     XEvent *event;
  5169.     Boolean *continue_flag;
  5170. {
  5171.   int i;
  5172.   KeySym ks;
  5173.   XComposeStatus compose;
  5174.   KeySym mykey;
  5175.   static int tx = 0;
  5176.   static char bst[4] = { 8,32,8,0 };
  5177.   static char eol[3] = { 13,10,0 };
  5178.   static char keytext[32], sendtext[128];
  5179.  
  5180.   switch (event->type) {
  5181.     case KeyPress :
  5182.     i = XLookupString( &event->xkey, keytext, 32, &mykey,
  5183.             &compose );
  5184.  
  5185.     if( dbg ) fprintf( stderr,
  5186.         "In keyevent KEYPRESS [i=%d, mykey=0x%x tx=%d]  keytext=>>%s<<\n",
  5187.                 i, mykey, tx, keytext );
  5188.  
  5189.     if( i >= 1 && mykey >= 0 ) {
  5190.         if( keytext[0] == '\n' || keytext[0] == '\r') {    /* newline */
  5191.         fputs( eol, stderr );
  5192.  
  5193.             sendtext[tx++] = '\n';
  5194.             sendtext[tx] = 0;
  5195.  
  5196.         /* got a line, now process it before sending */
  5197.         if( process_kbd( sendtext, exec_stdin ) != 0 ) {
  5198.                 fprintf( exec_stdin, "%s", sendtext );
  5199.                 fflush( exec_stdin );
  5200.         }
  5201.             tx = 0;
  5202.             keyecho = TRUE;            /* Allow 1 line of no echo */
  5203.         }
  5204.         else if( keytext[0] == 0x15 ) {    /* delete */
  5205.             while( tx > 0 ) { 
  5206.                 tx--;
  5207.                 if( keyecho ) fputs( bst, stderr );
  5208.             }
  5209.         }
  5210.                         /* backspace */
  5211.         else if( keytext[0] == 0x08 || mykey == (KeySym)(-1) ) {
  5212.             if( tx > 0 ) { 
  5213.                 tx--;
  5214.                 if( keyecho ) fputs( bst, stderr );
  5215.             }
  5216.         }
  5217.         else if( keytext[0] == 0x10 ) {    /* CNTRL-P */
  5218.             if( keyecho ) keyecho = FALSE;
  5219.             else keyecho = TRUE;
  5220.         }
  5221.         else if( tx < 127 && keytext[0] >= 0x20 ) {    /* normal char */
  5222.             sendtext[tx++] = keytext[0];
  5223.             keytext[1] = 0;
  5224.             if( keyecho ) fputs( keytext, stderr );
  5225.         }
  5226.     }
  5227.         break;
  5228.     case MappingNotify:
  5229.         XRefreshKeyboardMapping (&(event->xmapping));
  5230.         break;
  5231.     default:
  5232.       if( dbg ) fprintf( stderr, "In keyevent Unknown Type 0x%x\n",
  5233.         event->type );
  5234.       break;
  5235.   } 
  5236.   fflush( stderr );
  5237. }
  5238. #endif /* NOKEYGRAB */
  5239.  
  5240. static void CursorColor( w, client_data, call_data )
  5241.     GobanWidget w;
  5242.     XtPointer client_data, call_data;
  5243. {
  5244.     makemove( (-1), (-1), ++currentmove, EMPTY, STEPMOVE );
  5245.     boardchanged = mouseflag = TRUE;
  5246.     highlight( TRUE );
  5247.     set_cursor_color( colorflag+1 );
  5248. }
  5249.  
  5250. static void StepForward( w, client_data, call_data )
  5251.     GobanWidget w;
  5252.     XtPointer client_data, call_data;
  5253. {
  5254.     int i, x, y, flag;
  5255.  
  5256.     if( move < 0 ) {
  5257.         beep();
  5258.         highlight( FALSE );
  5259.         fprintf( stderr, "\nLOCAL:  No active game to step\n" );
  5260.         fflush( stderr );
  5261.         fprintf( exec_stdin, "\n" );
  5262.         fflush( exec_stdin );
  5263.         return;
  5264.     }
  5265.  
  5266.     if( stepmove >= move || statusflag ) {
  5267.         beep();
  5268.         return;
  5269.     }
  5270.     else if( stepmove < 0 ) stepmove = 0;
  5271.     else {
  5272.         ++stepmove;
  5273.         currentmove = stepmove;
  5274.     }
  5275.  
  5276.     if( dbg )
  5277.         fprintf( stderr, "StepForward entered [stepmove=%d, move=%d]\n",
  5278.             stepmove, move );
  5279.  
  5280.     boardchanged = TRUE;
  5281.  
  5282.     if( mouseflag ) {
  5283.         do_refresh( stepmove, NULL, STEPMOVE );
  5284.         mouseflag = FALSE;
  5285.     }
  5286.     else {
  5287.         if( stepmove == 0 && handicap > 0 ) {
  5288.             sethandicap( handicap, STEPMOVE );
  5289.         }
  5290.         else {
  5291.             getmove( stepmove, &x, &y, &flag );
  5292.             if( stepmove % 2 ) {
  5293.                 GbSetPoint( goban, x, y, GbWhiteStone, TRUE );
  5294.                 makemove( x, y, stepmove, GbWhiteStone, STEPMOVE );
  5295.         }
  5296.             else {
  5297.                 GbSetPoint( goban, x, y, GbBlackStone, TRUE );
  5298.                 makemove( x, y, stepmove, GbBlackStone, STEPMOVE );
  5299.         }
  5300.         }
  5301.     }
  5302.  
  5303.     if( stepmove < move ) boardchanged = TRUE;
  5304.     else boardchanged = FALSE;
  5305.  
  5306.     set_cursor_color( stepmove );
  5307.     if( stepmove >= move ) highlight( FALSE );
  5308. }
  5309.  
  5310. static void StepBack( w, client_data, call_data )
  5311.     GobanWidget w;
  5312.     XtPointer client_data, call_data;
  5313. {
  5314.     int x, y, flag;
  5315.  
  5316.     if( dbg ) fprintf( stderr, "StepBack entered [stepmove=%d, move=%d]\n",
  5317.             stepmove, move );
  5318.  
  5319.     if( move < 0 ) {
  5320.         beep();
  5321.         highlight( FALSE );
  5322.         fprintf( stderr, "\nLOCAL:  No active game to step\n" );
  5323.         fflush( stderr );
  5324.         fprintf( exec_stdin, "\n" );
  5325.         fflush( exec_stdin );
  5326.         return;
  5327.     }
  5328.  
  5329.     if( stepmove < 0 || statusflag ) {
  5330.         beep();
  5331.         return;
  5332.     }
  5333.     else if( stepmove > move ) stepmove = move;
  5334.     else if( stepmove == 0 ) ClearBoard();
  5335.     else {
  5336.  
  5337.         boardchanged = TRUE;
  5338.  
  5339.         /* only do full refresh if this move caused any captures, or if
  5340.          * the board is dirty
  5341.          */
  5342.         getmove( stepmove, &x, &y, &flag );
  5343.         if( !flag && !mouseflag ) {
  5344.             GbSetPoint( goban, x, y, GbEmptyPoint, TRUE );
  5345.         removemove( stepmove, STEPMOVE );
  5346.             getmove( stepmove-1, &x, &y, &flag );
  5347.             GbSetPoint( goban, x, y, (((stepmove-1)%2)+1), TRUE );
  5348.         }
  5349.         else {
  5350.             do_refresh( stepmove-1, NULL, STEPMOVE );
  5351.         mouseflag = FALSE;
  5352.         }
  5353.     }
  5354.  
  5355.     --stepmove;
  5356.     currentmove = stepmove;
  5357.     set_cursor_color( stepmove );
  5358.     highlight( TRUE );
  5359. }
  5360.  
  5361. static void InputStone( w, event )
  5362.     GobanWidget w;
  5363.     XButtonEvent *event;
  5364. {
  5365.     Position x = event->x;
  5366.     Position y = event->y;
  5367.  
  5368.     if( GbGetStoneFromPosition( w, &x, &y ) == TRUE ) {
  5369.         if( dbg ) fprintf( stderr, "Input stone at %c%d\n",
  5370.                 'A' + (x > 8 ? x + 1 : x) - 1, y );
  5371.     }
  5372.     else {
  5373.         beep();
  5374.         return;
  5375.     }
  5376.  
  5377.     if( observeflag != PLAYING && observeflag != SCORING ) {
  5378.         beep();
  5379.         return;
  5380.     }
  5381.  
  5382.     fprintf( exec_stdin, "%c%d\n", 'A' + (x > 8 ? x + 1 : x) - 1, y );
  5383.     fflush( exec_stdin );
  5384. }
  5385.  
  5386. static void AlternateStone( w, event )
  5387.     GobanWidget w;
  5388.     XButtonEvent *event;
  5389. {
  5390.     int ob;
  5391.     Position x = event->x;
  5392.     Position y = event->y;
  5393.  
  5394.     if( GbGetStoneFromPosition( w, &x, &y ) == TRUE ) {
  5395.         if( dbg ) fprintf( stderr, "Alternate stone at %c%d\n",
  5396.                 'A' + (x > 8 ? x + 1 : x) - 1, y );
  5397.     }
  5398.     else {
  5399.         beep();
  5400.         return;
  5401.     }
  5402.  
  5403.     if( statusflag ) {
  5404.         beep();
  5405.         return;
  5406.     }
  5407.  
  5408.     ++currentmove;
  5409.     if( gameno < 0 ) gameno = 0;
  5410.     boardchanged = mouseflag = TRUE;
  5411.     if( colorflag == BLACK ) {
  5412.         GbSetPoint( goban, x, y, GbBlackStone, TRUE );
  5413.         makemove( x, y, currentmove, GbBlackStone, STEPMOVE );
  5414.     }
  5415.     else {
  5416.         GbSetPoint( goban, x, y, GbWhiteStone, TRUE );
  5417.         makemove( x, y, currentmove, GbWhiteStone, STEPMOVE );
  5418.     }
  5419.     set_cursor_color( colorflag+1 );
  5420.     highlight( TRUE );
  5421. }
  5422.  
  5423.  
  5424. static void RemoveStone( w, event )
  5425.     GobanWidget w;
  5426.     XButtonEvent *event;
  5427. {
  5428.     Position x = event->x;
  5429.     Position y = event->y;
  5430.  
  5431.     if (GbGetStoneFromPosition (w, &x, &y) == TRUE) {
  5432.         if( dbg ) fprintf ( stderr, "Remove stone at %c%d\n",
  5433.                     'A' + (x > 8 ? x + 1 : x) - 1, y);
  5434.     }
  5435.  
  5436.     if( statusflag ) {
  5437.         beep();
  5438.         return;
  5439.     }
  5440.  
  5441.     /* XXX there is a slight glitch here: we do not remove stones
  5442.      * from the board table, so they still interact when testing
  5443.      * for dead stone removal and "Refresh(Local)"
  5444.      */
  5445.     GbSetPoint( goban, x, y, GbEmptyPoint, TRUE );
  5446.  
  5447.     boardchanged = mouseflag = TRUE;
  5448.     highlight( TRUE );
  5449. }
  5450.  
  5451. void Ticker( client_data, timer )
  5452.     XtPointer client_data;
  5453.     XtIntervalId *timer;
  5454. {
  5455.     XtAppAddTimeOut( (XtAppContext)client_data, 1000, Ticker, client_data );
  5456.     if( move < 0 || !observeflag || statusflag ) return;
  5457.  
  5458.     else if( move % 2 ) {
  5459.         if( dbg ) fprintf( stderr, "TIMER EVEN [B]\n" );
  5460.         --p2_sec;
  5461.         fix_btime( p2_sec, p2_byoyomi );
  5462.     }
  5463.     else {
  5464.         if( dbg ) fprintf( stderr, "TIMER ODD [W]\n" );
  5465.         --p1_sec;
  5466.         fix_wtime( p1_sec, p1_byoyomi );
  5467.     }
  5468. }
  5469.  
  5470. void SetCursor ( cs )
  5471.     int cs;
  5472. {
  5473.     Arg args[1];
  5474.  
  5475.     switch (cs) {
  5476.         case GbCBlackStone : 
  5477.         XtSetArg   (args[0], XtNcursor, GbCBlackStone);
  5478.         if( dbg ) fprintf ( stderr, "Set cursor to : Black \n"); 
  5479.         break;
  5480.         case GbCWhiteStone : 
  5481.         XtSetArg   (args[0], XtNcursor, GbCWhiteStone );
  5482.         if( dbg ) fprintf ( stderr, "Set cursor to : White\n"); 
  5483.         break;
  5484.         case XC_question_arrow :
  5485.         XtSetArg   (args[0], XtNcursor, XC_question_arrow );  
  5486.         if( dbg ) fprintf ( stderr, "Set cursor to : Question\n"); 
  5487.         break;
  5488.     }
  5489.  
  5490.     XtSetValues (goban, args, 1);
  5491. }
  5492.  
  5493. void RefreshHost( w, client_data, call_data )
  5494.     GobanWidget w;
  5495.     XtPointer client_data, call_data;
  5496. {
  5497.     if( gameno < 0 ) {
  5498.         beep();
  5499.         highlight( FALSE );
  5500.         fprintf( stderr, "\nLOCAL:  No active game to refresh\n" );
  5501.         fflush( stderr );
  5502.         highlight( FALSE );
  5503.         GbClearBoard( goban );
  5504.         initboard( boardsize );
  5505.         fprintf( exec_stdin, "\n" );
  5506.         fflush( exec_stdin );
  5507.     }
  5508.     else {
  5509.         SetCursor ( GbCBlackStone );
  5510.         move = (-1);
  5511.         refreshboard();
  5512.         fprintf( exec_stdin, "moves %d\n", gameno );
  5513.         fflush( exec_stdin );
  5514.     }
  5515. }
  5516.  
  5517. int refreshboard() {
  5518.     if( gameno < 0 ) {
  5519.         highlight( FALSE );
  5520.         fprintf( stderr, "\nLOCAL: No active game to refresh\n" );
  5521.         fflush( stderr );
  5522.         fprintf( exec_stdin, "\n" );
  5523.         fflush( exec_stdin );
  5524.         return;
  5525.     }
  5526.  
  5527.     boardchanged = mouseflag = statusflag = FALSE;
  5528.     highlight( FALSE );
  5529.     GbClearBoard( goban );
  5530.     stepmove = (-1);
  5531.     currentmove = (-1);
  5532.     handicap = 0;
  5533.     update_handicap( 0 );
  5534.     initboard( boardsize );
  5535. }
  5536.  
  5537. static void ClearBoard() {
  5538.     GbClearBoard( goban );
  5539.     stepmove = (-2);
  5540.     currentmove = (-1);
  5541.     boardchanged = TRUE;
  5542.     mouseflag = FALSE;
  5543.     highlight( TRUE );
  5544.     set_cursor_color( 1 );
  5545.     clear_stepboard();
  5546. }
  5547.  
  5548. static void SetSize() {
  5549.     Arg       args[1];
  5550.     static int beenhere = FALSE;
  5551.  
  5552.     if( !beenhere ) {
  5553.         boardsize = 13;
  5554.         beenhere = TRUE;
  5555.     }
  5556.  
  5557.     switch( boardsize ) {
  5558.     case 9:
  5559.         boardsize = 13;
  5560.         break;
  5561.     case 13:
  5562.         boardsize = 19;
  5563.         break;
  5564.     case 19:
  5565.     default:
  5566.         boardsize = 9;
  5567.         break;
  5568.     }
  5569.  
  5570.     if( dbg ) fprintf ( stderr, "Set size to : %d\n", boardsize);
  5571.  
  5572.     set_cursor_color( 1 );
  5573.  
  5574.     XtSetArg( args[0], XtNgameSize, (Dimension)boardsize );
  5575.     XtSetValues( goban, args, 1 );
  5576. }
  5577.  
  5578. static void SetCoordinates() {
  5579.     Arg     args[1];
  5580.     Boolean coordinates;
  5581.  
  5582.     XtSetArg    (args[0], XtNdisplayCoordinates, &coordinates);
  5583.     XtGetValues (goban, args, 1);
  5584.     
  5585.     switch (coordinates) {
  5586.         case FALSE : 
  5587.         XtSetArg (args[0], XtNdisplayCoordinates, TRUE) ; 
  5588.         if( dbg ) fprintf( stderr, "Set coordinates to : TRUE \n");
  5589.         break;
  5590.         case TRUE  : 
  5591.         XtSetArg (args[0], XtNdisplayCoordinates, FALSE); 
  5592.         if( dbg ) fprintf( stderr, "Set coordinates to : FALSE \n");
  5593.         break;
  5594.     }
  5595.  
  5596.     XtSetValues (goban, args, 1);
  5597. }
  5598.  
  5599. static void SetupBoard() {
  5600.     char s[40];
  5601.     
  5602.     XtPopup (bw, XtGrabNone);
  5603.     SetSize();
  5604.     set_cursor_color( 1 );
  5605.     sprintf( s, "%s [%s]", BOARDTITLE, PATCHLEVEL );
  5606.     XSetStandardProperties( XtDisplay(bw), XtWindow(bw),
  5607.             s, BOARDICON, NULL, NULL, 0, NULL );
  5608.  
  5609. }
  5610.  
  5611.  
  5612.  
  5613. static void Redisplay() {
  5614.     GbRedisplayBoard (goban);
  5615. }
  5616.  
  5617. XtActionsRec actions[] = {
  5618.     { "inputStone", (XtActionProc)InputStone },
  5619.     { "removeStone", (XtActionProc)RemoveStone },
  5620.     { "addStone", (XtActionProc)AlternateStone },
  5621. };
  5622.  
  5623. main( argc, argv )
  5624.     int argc;
  5625.     char **argv;
  5626. {
  5627.     extern void exit ();
  5628.     extern char *optarg;
  5629.     extern int optind;
  5630.     int c;
  5631.     int xtargc = 0;
  5632.     Arg args[8];
  5633.     int j;
  5634.     extern int getopt();
  5635.  
  5636.     get_cmd();
  5637.     if( cmd[0] == '\0' ) strcpy( cmdline, CMD );
  5638.     else strcpy( cmdline, (char *)cmd );
  5639.  
  5640.     initboard( boardsize );
  5641.     move = stepmove = (-1);
  5642.     currentmove = (-1);
  5643.     statusflag = FALSE;
  5644.  
  5645.     toplevel = XtAppInitialize( &app_context, "XIgc", NULL, 0, &argc, argv,
  5646.             NULL, NULL, 0);
  5647.  
  5648.     /* any more command-line args? */
  5649.     while( (c=getopt( argc, argv, "?c:ds" )) != (-1) ) {
  5650.         switch( c ) {
  5651.         case 'd':    /* debug mode */
  5652.             dbg = TRUE;
  5653.             break;
  5654.         case 's':    /* stippled board */
  5655.             stippleflag = TRUE;
  5656.             break;
  5657.         case 'c':    /* command line for comm program */
  5658.             strcpy( cmdline, optarg );
  5659.             cmdflag = TRUE;
  5660.             break;
  5661.         case '?':
  5662.         default:
  5663.             fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  5664.                 fprintf( stderr, USAGE, argv[0] );
  5665.             exit( (-1) );
  5666.             break;
  5667.         }
  5668.     }
  5669.  
  5670.     if( optind != argc ) {
  5671.         fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  5672.         fprintf( stderr, USAGE, argv[0] );
  5673.         exit( (-1) );
  5674.     }
  5675.  
  5676.     bw = XtCreatePopupShell( "board", topLevelShellWidgetClass, toplevel,
  5677.             NULL, 0);
  5678.     form = XtCreateManagedWidget( "form", formWidgetClass, toplevel, NULL,
  5679.             0);
  5680.     j = 0;
  5681.     XtSetArg(args[j], XtNlabel, "Game:               " ); ++j;
  5682.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5683.     gamew = XtCreateManagedWidget( "gamew", labelWidgetClass, form,
  5684.                         args, j );
  5685.  
  5686.     j = 0;
  5687.     XtSetArg(args[j], XtNlabel, "Handicap:           " ); ++j;
  5688.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5689.     hcapw = XtCreateManagedWidget( "hcapw", labelWidgetClass, form,
  5690.                         args, j );
  5691.     j = 0;
  5692.     XtSetArg(args[j], XtNlabel, "White:              " ); ++j;
  5693.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5694.     whitew = XtCreateManagedWidget( "whitew", labelWidgetClass, form,
  5695.                         args, j );
  5696.     j = 0;
  5697.     XtSetArg(args[j], XtNlabel, "Black:              " ); ++j;
  5698.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5699.     blackw = XtCreateManagedWidget( "blackw", labelWidgetClass, form,
  5700.                         args, j );
  5701.     j = 0;
  5702.     XtSetArg(args[j], XtNlabel, "Captured:           " ); ++j;
  5703.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5704.     captw = XtCreateManagedWidget( "captw", labelWidgetClass, form,
  5705.                         args, j );
  5706.     j = 0;
  5707.     XtSetArg(args[j], XtNlabel, "Captured:           " ); ++j;
  5708.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5709.     captb = XtCreateManagedWidget( "captb", labelWidgetClass, form,
  5710.                         args, j );
  5711.     j = 0;
  5712.     XtSetArg(args[j], XtNlabel, "Time:               " ); ++j;
  5713.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5714.     timew = XtCreateManagedWidget( "timew", labelWidgetClass, form,
  5715.                         args, j );
  5716.     j = 0;
  5717.     XtSetArg(args[j], XtNlabel, "Time:               " ); ++j;
  5718.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5719.     timeb = XtCreateManagedWidget( "timeb", labelWidgetClass, form,
  5720.                         args, j );
  5721.     j = 0;
  5722.     XtSetArg(args[j], XtNlabel, "Last:                                     " ); ++j;
  5723.     XtSetArg(args[j], XtNjustify, XtJustifyLeft ); ++j;
  5724.     lastw = XtCreateManagedWidget( "lastw", labelWidgetClass, form,
  5725.                         args, j );
  5726.     j = 0;
  5727.     XtSetArg( args[j], XtNgameSize, 19 ); ++j;
  5728.     XtSetArg( args[j], XtNcursor, GbCBlackStone); ++j;
  5729.     goban = XtCreateManagedWidget( "goban", gobanWidgetClass, bw, args,
  5730.             j);
  5731.  
  5732.     refresh = XtCreateManagedWidget( "refresh", commandWidgetClass, form,
  5733.             NULL, 0);
  5734.     cursorcolor = XtCreateManagedWidget( "cursorcolor", commandWidgetClass,
  5735.             form, NULL, 0);
  5736.     clearb = XtCreateManagedWidget( "clearb", commandWidgetClass, form,
  5737.             NULL, 0);
  5738.     stepf = XtCreateManagedWidget( "stepf", commandWidgetClass, form, NULL,
  5739.             0);
  5740.     stepb = XtCreateManagedWidget( "stepb", commandWidgetClass, form, NULL,
  5741.             0);
  5742.     refreshstep = XtCreateManagedWidget( "refreshstep", commandWidgetClass,
  5743.             form, NULL, 0);
  5744.  
  5745.     localrefresh = XtCreateManagedWidget( "localrefresh",
  5746.             commandWidgetClass, form, NULL, 0);
  5747.     size = XtCreateManagedWidget( "size", commandWidgetClass, form, NULL,    
  5748.             0);
  5749.     savegame = XtCreateManagedWidget( "savegame", commandWidgetClass,
  5750.             form, NULL, 0);
  5751.     savecurrent = XtCreateManagedWidget( "savecurrent", commandWidgetClass,
  5752.             form, NULL, 0);
  5753.     coordinates = XtCreateManagedWidget( "coordinates", commandWidgetClass,
  5754.             form, NULL, 0);
  5755.     quit = XtCreateManagedWidget( "quit", commandWidgetClass, form, NULL,
  5756.             0);
  5757.  
  5758.     XtAppAddActions (app_context, actions, XtNumber(actions));
  5759.  
  5760.     XtAddCallback (refresh, XtNcallback, (XtCallbackProc)RefreshHost,
  5761.             NULL);
  5762.     XtAddCallback (cursorcolor, XtNcallback, (XtCallbackProc)CursorColor,
  5763.             NULL); 
  5764.     XtAddCallback (clearb, XtNcallback, (XtCallbackProc)ClearBoard, NULL);
  5765.     XtAddCallback (stepf, XtNcallback, (XtCallbackProc)StepForward, NULL);
  5766.     XtAddCallback (stepb, XtNcallback, (XtCallbackProc)StepBack, NULL);
  5767.     XtAddCallback (refreshstep, XtNcallback, (XtCallbackProc)RefreshStep,
  5768.             NULL);
  5769.     XtAddCallback (localrefresh, XtNcallback, (XtCallbackProc)LocalRefresh,
  5770.             NULL);
  5771.     XtAddCallback (size, XtNcallback, (XtCallbackProc)SetSize, NULL);
  5772.     XtAddCallback (savegame, XtNcallback, (XtCallbackProc)SaveGame,
  5773.             (XtPointer)REALMOVE );
  5774.     XtAddCallback (savecurrent, XtNcallback, (XtCallbackProc)SaveGame,
  5775.             (XtPointer)STEPMOVE );
  5776.     XtAddCallback (coordinates, XtNcallback, (XtCallbackProc)SetCoordinates,
  5777.             NULL);
  5778.     XtAddCallback (quit, XtNcallback, (XtCallbackProc)Quit, NULL);
  5779.  
  5780.     XtRealizeWidget (toplevel);
  5781.  
  5782.         XSetStandardProperties( XtDisplay(toplevel), XtWindow(toplevel),
  5783.         TITLE, ICONTITLE, NULL, argv, argc, NULL );
  5784.  
  5785.     SetupBoard();
  5786.  
  5787.     /* grab keystrokes when mouse is in board or menu windows */
  5788. #ifndef NOKEYGRAB
  5789.     XtGrabKey( bw, AnyKey, AnyModifier, FALSE, 
  5790.         GrabModeAsync, GrabModeAsync );
  5791.     XtAddEventHandler( bw, KeyPressMask | KeymapStateMask, FALSE, 
  5792.         (XtEventHandler)keyevent, NULL );
  5793.  
  5794.     XtGrabKey(toplevel, AnyKey, AnyModifier, FALSE, 
  5795.         GrabModeAsync, GrabModeAsync);
  5796.     XtAddEventHandler(toplevel, KeyPressMask | KeymapStateMask, FALSE, 
  5797.         (XtEventHandler)keyevent, NULL);
  5798. #endif /* NOKEYGRAB */
  5799.  
  5800.     setup_filter( &exec_stdin, &exec_stdout, &exec_stderr );
  5801.     input0id = XtAppAddInput( app_context, fileno(stdin),
  5802.         (XtPointer)(XtInputReadMask), read_kbd,
  5803.         (caddr_t)fileno(stdin) );
  5804.     input1id = XtAppAddInput( app_context, fileno(exec_stdout),
  5805.         (XtPointer)(XtInputReadMask), read_filter,
  5806.         (caddr_t)fileno(exec_stdout) );
  5807.     input2id = XtAppAddInput( app_context, fileno(exec_stderr),
  5808.         (XtPointer)(XtInputReadMask), read_filter,
  5809.         (caddr_t)fileno(exec_stderr) );
  5810.  
  5811.     XtAppAddTimeOut( XtWidgetToApplicationContext(toplevel), 1000, Ticker,
  5812.              XtWidgetToApplicationContext(toplevel) );
  5813.     XtAppMainLoop (app_context);
  5814. }
  5815.  
  5816.  
  5817. /* this one reads input from the comm channel, prints it, and also
  5818.  * calls process_input for parsing
  5819.  */
  5820. void read_filter( client_data, source, id )
  5821.     int client_data;
  5822.     int *source;
  5823.     char *id;
  5824. {
  5825.     char str[LINESIZE+1], *s;
  5826.     int ret, i, code;
  5827.  
  5828.     if( dbg ) fprintf( stderr,
  5829.         "********* in read_filter() fd=%d **********\n", client_data );
  5830.     ret = read( client_data, str, LINESIZE );
  5831.     if( ret <= 0 ) {
  5832.         XtRemoveInput( input1id );
  5833.         XtRemoveInput( input2id );
  5834.         fprintf( stderr, "Closing pipes to comm process\n" );
  5835.         return;
  5836.     }
  5837.     else str[ret] = '\0';
  5838.  
  5839.     /* just check once more to be sure we have only 7-bit chars */
  5840.     for( i=0; i<ret; ++i ) str[i] &= 0x7f;
  5841.  
  5842.     process_input( str );
  5843.  
  5844.     if( dbg ) fprintf( stderr,
  5845.         "######### leave read_filter() [%d chars] #########\n", ret );
  5846. }
  5847.  
  5848. /* this one just reads lines from the kbd and passes them to comm stdin */
  5849. void read_kbd( client_data, source, id )
  5850.     int client_data;
  5851.     int *source;
  5852.     char *id;
  5853. {
  5854.     char str[LINESIZE+1];
  5855.     int ret;
  5856.  
  5857.     if( dbg ) fprintf( stderr,
  5858.         "********* in read_kbd() fd=%d **********\n", client_data );
  5859.     ret = read( client_data, str, LINESIZE );
  5860.     if( ret <= 0 ) {
  5861.         fprintf( stderr, "\nKBD: no input!  (ignored)\n" );
  5862.         return;
  5863.     }
  5864.     else str[ret] = '\0';
  5865.  
  5866.     /*XXX got to do something about the CTRL-P to make it work right
  5867.      * when cursor is in xterm window
  5868.      */
  5869.  
  5870.     if( process_kbd( str, exec_stdin ) != 0 ) {
  5871.         fputs( str, exec_stdin );
  5872.         fflush( exec_stdin );
  5873.     }
  5874.  
  5875.     if( dbg ) fprintf( stderr,
  5876.         "######### leave read_kbd() [%d chars] #########\n", ret );
  5877. }
  5878.  
  5879. setMark( i, j, t )
  5880.     int i, j;
  5881.     unsigned char t;
  5882. {
  5883.     GbSetMark( goban, (Position)i, (Position)j, t, 0 );
  5884. }
  5885.  
  5886. drawStone( i, h, t, flag )
  5887.     int i, h;
  5888.     int t;    /* 0=remove, 1=black, 2=white */
  5889.     unsigned char flag;
  5890. {
  5891.     if( dbg ) fprintf( stderr, "Drawing stone at %d,%d  (%d)\n", i, h, t );
  5892.     GbSetPoint( goban, i, h, t, flag );
  5893.  
  5894. }
  5895.  
  5896. update_status( g, black, white, bcapt, wcapt, btime, wtime, bbyo, wbyo )
  5897.     int g;
  5898.     char *white, *black;
  5899.     int wcapt, bcapt, wtime, btime;
  5900.     int bbyo, wbyo;
  5901. {
  5902.     Arg args[8];
  5903.     int j;
  5904.     char str[80];
  5905.  
  5906.     update_gameno( g );
  5907.  
  5908.     if( g < 0 ) sprintf( str, "Black:" );
  5909.     else sprintf( str, "Black: %s", black );
  5910.     j = 0;
  5911.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5912.     XtSetValues( blackw, args, j );
  5913.  
  5914.     if( g < 0 ) sprintf( str, "White:" );
  5915.     else sprintf( str, "White: %s", white );
  5916.     j = 0;
  5917.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5918.     XtSetValues( whitew, args, j );
  5919.  
  5920.     if( g < 0 ) sprintf( str, "Captured:" );
  5921.     else sprintf( str, "Captured: %d", wcapt );
  5922.     j = 0;
  5923.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5924.     XtSetValues( captw, args, j );
  5925.  
  5926.     if( g < 0 ) sprintf( str, "Captured:" );
  5927.     else sprintf( str, "Captured: %d", bcapt );
  5928.     j = 0;
  5929.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5930.     XtSetValues( captb, args, j );
  5931.  
  5932.     fix_wtime( wtime, wbyo );
  5933.     fix_btime( btime, bbyo );
  5934. }
  5935.  
  5936. update_move( last )
  5937.     char *last;
  5938. {
  5939.     int i, j;
  5940.     char str[80];
  5941.     Arg args[8];
  5942.  
  5943.     if( last == NULL ) sprintf( str, "Last:" );
  5944.     else {
  5945.         sprintf( str, "Last: %s", last );
  5946.         for( i=0; str[i] != '\0' && str[i] != '\r' && str[i] != '\n'; ++i );
  5947.         str[i] = '\0';
  5948.     }
  5949.  
  5950.     j = 0;
  5951.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5952.     XtSetValues( lastw, args, j );
  5953. }
  5954.  
  5955. update_handicap( hcap )
  5956.     int hcap;
  5957. {
  5958.     Arg args[8];
  5959.     int j;
  5960.     char str[80];
  5961.  
  5962.     if( hcap < 0 ) sprintf( str, "Handicap:" );
  5963.     else sprintf( str, "Handicap: %d", hcap );
  5964.     j = 0;
  5965.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5966.     XtSetValues( hcapw, args, j );
  5967. }
  5968.  
  5969. update_gameno( g )
  5970.     int g;
  5971. {
  5972.     Arg args[8];
  5973.     int j;
  5974.     char str[80];
  5975.  
  5976.     if( g < 0 ) sprintf( str, "Game:" );
  5977.     else sprintf( str, "Game: %d", g );
  5978.     j = 0;
  5979.     XtSetArg(args[j], XtNlabel, str ); ++j;
  5980.     XtSetValues( gamew, args, j );
  5981. }
  5982.  
  5983. /* get the server config file, with command line to execute, if any
  5984.  * return (-1) if no
  5985.  *    1) a file $HOME/.xigcrc
  5986.  *    2) in this file:
  5987.  *        COMMAND   cmd line to execute
  5988.  *        QUITCOMMAND cmd to quit from "cmd"
  5989.  *        SAVEFORMAT  SGF or TEXT format for "Save game" menu item
  5990.  */
  5991. static int get_cmd() {
  5992.     char *ret;
  5993.     FILE *fp;
  5994.     char str[80];
  5995.     int cnt = 0;
  5996.     extern char *getenv();
  5997.     int len;
  5998.  
  5999.     cmd[0] = '\0';
  6000.     quitcmd[0] = '\0';
  6001.  
  6002.     ret = getenv( "HOME" );
  6003.     if( ret == NULL ) return( cnt );
  6004.  
  6005.     sprintf( str, "%s/.xigcrc", ret );
  6006.     if( dbg ) fprintf( stderr, "config file: >>%s<<\n", str );
  6007.     fp = fopen( str, "r" );
  6008.     if( fp  == NULL ) {
  6009.         if( dbg ) fprintf( stderr, "can't open config file >>%s<<\n", str );
  6010.         return( cnt );
  6011.     }
  6012.     
  6013.     while( fgets( str, 80, fp ) != NULL ) {
  6014.         len = strlen( str );
  6015.         if( len < 4 || str[0] == '#' ) continue;
  6016.         str[len-1] = '\0';
  6017.         if( dbg ) fprintf( stderr, ">>%s<<\n", str );
  6018.         if( strncmp( str, "COMMAND", 7 ) == 0 ) {
  6019.         if( cmd[0] == '\0' ) {
  6020.             strcpy( (char *)cmd, &str[8] );
  6021.             if( dbg ) fprintf( stderr, "get_cmd: cmd >>%s<<\n" , cmd );
  6022.             ++cnt;
  6023.         }
  6024.         }
  6025.         if( strncmp( str, "QUITCOMMAND", 11 ) == 0 ) {
  6026.         if( quitcmd[0] == '\0' ) {
  6027.             strcpy( (char *)quitcmd, &str[12] );
  6028.             if( dbg ) fprintf( stderr, "get_cmd: quitcmd >>%s<<\n",
  6029.                     quitcmd );
  6030.             ++cnt;
  6031.             }
  6032.         }
  6033.         if( strncmp( str, "SAVEFORMAT", 10 ) == 0 ) {
  6034.         if( saveformat == (-1) ) {
  6035.             if( strncmp( &str[11], "TEXT", 4 ) == 0 ||
  6036.                 strncmp( &str[11], "text", 4 ) == 0 ) saveformat = TEXT;
  6037.             else if( strncmp( &str[11], "SGF", 3 ) == 0 ||
  6038.                 strncmp( &str[11], "sgf", 3 ) == 0 ) saveformat = SGF;
  6039.             ++cnt;
  6040.         }
  6041.         }
  6042.     }
  6043.  
  6044.     fclose( fp );
  6045.     return( cnt );
  6046. }
  6047.  
  6048. fix_wtime( wtime, wbyo )
  6049.     int wtime;
  6050.     int wbyo;
  6051. {
  6052.     Arg args[8];
  6053.     int j;
  6054.     char str[80];
  6055.  
  6056.     if( wbyo > 0 ) {
  6057.         sprintf( str, "Byo Yomi: %d:%02.2d  %d",
  6058.         wtime/60, wtime%60, wbyo );
  6059.     }
  6060.     else {
  6061.         sprintf( str, "Time: %d:%02.2d", wtime/60, wtime%60 );
  6062.     }
  6063.     j = 0;
  6064.     XtSetArg(args[j], XtNlabel, str ); ++j;
  6065.     XtSetValues( timew, args, j );
  6066. }
  6067.  
  6068. fix_btime( btime, bbyo )
  6069.     int btime, bbyo;
  6070. {
  6071.     Arg args[8];
  6072.     int j;
  6073.     char str[80];
  6074.  
  6075.     if( bbyo > 0 ) {
  6076.         sprintf( str, "Byo Yomi: %d:%02.2d  %d",
  6077.         btime/60, btime%60, bbyo );
  6078.     }
  6079.     else {
  6080.         sprintf( str, "Time: %d:%02.2d", btime/60, btime%60 );
  6081.     }
  6082.     j = 0;
  6083.     XtSetArg(args[j], XtNlabel, str ); ++j;
  6084.     XtSetValues( timeb, args, j );
  6085. }
  6086. SHAR_EOF
  6087. fi
  6088. if test -f 'xigc.man'
  6089. then
  6090.     echo shar: "will not over-write existing file 'xigc.man'"
  6091. else
  6092. cat << \SHAR_EOF > 'xigc.man'
  6093. .TH xigc 1 "1/93"
  6094. .SH NAME
  6095. xigc \- X Window System Interface for the Internet Go Server
  6096. .br
  6097. igscomm \- Simple Communications Interface for the Internet Go Server
  6098. .SH SYNOPSIS
  6099. .in +.5i
  6100. .ti -.5i
  6101. .B
  6102. xigc [-TypicalXArgs] [-c "command line for communications"] [-s] [-d]
  6103. .P
  6104. .ti -.5i
  6105. .br
  6106. .B
  6107. igscomm [-d] [-e] [-h host-address] [-p port-address]
  6108. .P
  6109. .in -.5i
  6110. .SH DESCRIPTION
  6111. .B "xigc"
  6112. provides an X Window System interface to the Internet
  6113. Go Server (IGS).  It works with
  6114. .B "cu"
  6115. and
  6116. .B "rlogin"
  6117. for indirect access through intermediate machines, as well as
  6118. .B "telnet"
  6119. or other socket-based communications programs for direct Internet
  6120. access to IGS.
  6121. .B "igscomm,"
  6122. a primitive version of
  6123. .B "telnet,"
  6124. is also included.  Because of bugs associated with telnet use,
  6125. .B "xigc"
  6126. users are STRONGLY urged to use
  6127. .B "igscomm"
  6128. as their communications program if possible.  Use of
  6129. .B "telnet"
  6130. is NOT recommended.
  6131. .sp
  6132. .B "xigc"
  6133. provides a go board window, a menu window, and a communications
  6134. stream between the user and the IGS.  The communications window is just the
  6135. .B "xterm"
  6136. window when the application was executed.  All manual IGS commands
  6137. continue to work as usual, except that when the user is playing or observing
  6138. a game, moves are displayed on the go board in its own window.  When playing
  6139. a game, the user can click on a point on the board to send a move at that
  6140. point to the IGS.
  6141. .SH INSTALLATION
  6142. After unpacking the source distribution, use
  6143. .B "xmkmf"
  6144. followed by
  6145. .B "make depend"
  6146. to generate a Makefile for your environment.  
  6147. If you do not have
  6148. .B "xmkmf"
  6149. or
  6150. .B "imake,"
  6151. you may be able to adapt the file
  6152. .B "Makefile.hand,"
  6153. and use it as a Makefile for your system.
  6154. Then type
  6155. .B "make"
  6156. and then
  6157. .B "make install"
  6158. to install
  6159. .B "xigc"
  6160. and
  6161. .B "igscomm"
  6162. in your standard locations.
  6163. .sp
  6164. Make sure the file
  6165. .B "XIgc.ad"
  6166. is placed in your standard place for X11
  6167. application defaults (and named
  6168. .B "XIgc),"
  6169. or added to your
  6170. .B ".Xdefaults."
  6171. You can also do
  6172. .ti 10
  6173. .B
  6174. xrdb -merge XIgc.ad
  6175. .br
  6176. .P
  6177. after you start X but before running
  6178. .B "xigc."
  6179. You must do one of these things or
  6180. .B "xigc"
  6181. will not run!
  6182. .B "make install"
  6183. should install this file correctly.
  6184. .SH "XIGC COMMAND LINE"
  6185. Execute
  6186. .B "xigc"
  6187. from an
  6188. .B "xterm"
  6189. window.  This is required since the standard I/O
  6190. between the IGS and the user is handled through this window.  That is,
  6191. you cannot make
  6192. .B "xigc"
  6193. run from a menu item unless it is run through the
  6194. .B "-e"
  6195. option on an
  6196. .B "xterm"
  6197. window.
  6198. .sp
  6199. If you run
  6200. .B "xigc"
  6201. alone with no command-line arguments, it uses
  6202. .B "igscomm"
  6203. command for Internet communications, or you can use
  6204. .ti 10
  6205. .B
  6206. xigc -c "command line in quotes"
  6207. .br
  6208. .P
  6209. where the command line is another communications program you select.
  6210. For example:
  6211. .ti 10
  6212. .B
  6213. xigc -c "telnet 128.32.201.46 6969"
  6214. .P
  6215. .br
  6216. or
  6217. .ti 10
  6218. .B
  6219. xigc -c "cu uswat"
  6220. .P
  6221. .br
  6222. In addition to
  6223. .B "igscomm,"
  6224. the communications methods
  6225. .B "cu, rlogin"
  6226. and one version of
  6227. .B "telnet"
  6228. have been tested.  Most communications programs
  6229. should work, but your mileage may vary.  Note that
  6230. .B "telnet"
  6231. has some problems and should be avoided if possible.  Use
  6232. .B "igscomm"
  6233. if you can.  Even 1200 baud connections have acceptable performance!
  6234. .sp
  6235. You can change the default command by modifying a couple of #define lines
  6236. near the top of xigc.c, and/or by creating a personal command file (see below).
  6237. When you do this, you must also specify a character
  6238. sequence that is used to exit from the communications command.
  6239. .sp
  6240. You can also place many common X Window System parameters on the
  6241. .B "xigc"
  6242. command line.  If you do this, place all X arguments before any
  6243. .B "xigc"
  6244. arguments on the command line.  You will need to experiment to see
  6245. which X arguments work, and which items must be specified in the
  6246. application defaults.
  6247. .sp
  6248. Use the
  6249. .B "-s"
  6250. option to display the board with a light-gray stippled pattern instead
  6251. of a solid color.  This feature is most useful if you have a monochrome
  6252. display.  You can change the entry
  6253. .B "XIgc*goban*stipple"
  6254. in your application defaults file to be
  6255. .B "true"
  6256. to turn on stippling.  If you do this, the
  6257. .B "-s"
  6258. option will turn stippling off.
  6259. .sp
  6260. Other
  6261. .B "xigc"
  6262. command line options include
  6263. .B "-d"
  6264. (for debugging; not recommended).
  6265. .sp
  6266. There is another method of setting the communications command
  6267. name to execute.
  6268. You may place these commands in a file
  6269. .B "$HOME/.xigcrc."
  6270. For example:
  6271. .br
  6272. .ti 10
  6273. $ cat $HOME/.xigcrc
  6274. .br
  6275. .ti 10
  6276. COMMAND igscomm -h 128.32.201.46 -p 6969
  6277. .ti 10
  6278. .br
  6279. QUITCOMMAND .
  6280. .sp
  6281. Do not use any equal signs or quotes in your
  6282. .B .xigcrc
  6283. file.  The order of priority for these commands is
  6284. compiled-in defaults lowest, then
  6285. .B .xigcrc
  6286. file, and command-line option
  6287. highest.
  6288. .SH "SETUP"
  6289. After logging into the IGS for the first time with
  6290. .B "xigc,"
  6291. type
  6292. .ti 10
  6293. .B
  6294. toggle client on
  6295. .P
  6296. .br
  6297. to set up the IGS for communications with
  6298. .B "xigc."
  6299. If you go back to direct
  6300. .B "telnet"
  6301. connections to the IGS, you will need to
  6302. .ti 10
  6303. .B
  6304. toggle client off
  6305. .P
  6306. .br
  6307. and
  6308. .ti 10
  6309. .B
  6310. toggle verbose on
  6311. .P
  6312. .br
  6313. to restore your IGS environment to its original state.
  6314. .sp
  6315. When you are using
  6316. .B "igscomm"
  6317. or
  6318. .B "telnet"
  6319. through an intermediate system, such as with
  6320. .B "cu"
  6321. or
  6322. .B "rlogin,"
  6323. you may find that commands are echoed twice.  You can turn off
  6324. this extra echo by adding the
  6325. .B "-e"
  6326. command-line option for
  6327. .B "igscomm,"
  6328. or using the
  6329. .B "telnet"
  6330. command
  6331. .B "^E"
  6332. (CNTRL-E).  When you execute
  6333. .B "igscomm"
  6334. or
  6335. .B "telnet"
  6336. directly from
  6337. .B "xigc,"
  6338. you should not get the extra echo, and the
  6339. .B "^E"
  6340. or
  6341. .B "-e"
  6342. should not be needed.
  6343. .sp
  6344. Note that
  6345. .B "igscomm"
  6346. must run on the machine that is directly connected to the Internet,
  6347. or your gateway machine.
  6348. It does not support connection across multiple systems.
  6349. .sp
  6350. The application defaults set many of the options for how
  6351. .B "xigc"
  6352. will look and perform in your environment.  You can set the size,
  6353. color, labels, and other information in the
  6354. .B "XIgc"
  6355. file, or change the items in your
  6356. .B ".Xdefaults"
  6357. file.  Look at the X Window System documentation and the
  6358. .B "XIgc.ad"
  6359. file for more information about setting size, color, screen location,
  6360. and other display variables.
  6361. .SH "USE"
  6362. You can type commands into the
  6363. .B "xigc"
  6364. windows, or place a stone by clicking
  6365. the left mouse button at a location on the board, or remove a stone by
  6366. clicking the middle mouse button over a stone on the board.  The left
  6367. button sends a move to the IGS, but the middle button just removes a stone
  6368. from the board locally.  Use the menu to change the color of the placed
  6369. stone (and the cursor), refresh the board, save the game to a file,
  6370. exit, etc.
  6371. .sp
  6372. If the cursor is over the board or menu window (but not over the
  6373. command window), you can type CNTRL-P to disable character echo for
  6374. the rest of that input line.  This allows you to type in any passwords
  6375. or other information without displaying them to any observers.
  6376. Currently this feature does not work if the cursor is over the
  6377. .B "xterm"
  6378. or command window.
  6379. .sp
  6380. Mouse button 3 (right button) places a stone on the board locally,
  6381. but does not send the move to the host.  It also changes the color
  6382. of the stone for the next click, so that you can
  6383. play games or sequences locally by using button 3.
  6384. You can restore the game to its "real" state
  6385. with the "Refresh (Local)" menu item.  Stones placed with button 3
  6386. are not saved to a file with "Save Moves", but can be saved with
  6387. "Save to Current," which saves the current board position as a "game."
  6388. .sp
  6389. You can step back one move in the current game using the "Step Back" menu
  6390. item, and can step forward with "Step Forward."  If you add stones
  6391. to the board with button 3 from a stepped position (not the current
  6392. "real" board position), you may use "Refresh to Step" to restore the
  6393. board to the current step.  To step through a game from the beginning,
  6394. load the game with "observe n" or "Refresh (Host)", then "Clear" the
  6395. board, then "Step Forward" until you reach the last move played.
  6396. Note that when you have changed the board from the "real" game
  6397. position, either by stepping or by using button 2 or 3,  incoming moves
  6398. are not immediately displayed on the board.  Instead, incoming moves
  6399. cause the terminal to beep, and the "Refresh (Local)" menu item becomes
  6400. highlighted.  You must restore the game to its "real" state (usually
  6401. with "Refresh (Local)") before incoming moves are again displayed
  6402. as they arrive.
  6403. .sp
  6404. You can also look at a game you are not observing by using the IGS
  6405. command "status n," where n is the game number you wish to look at.
  6406. This causes the board to switch to the game you request.  This
  6407. display is not active, and you cannot step forward or back, or
  6408. add stones with the mouse buttons.  You must restore the observed
  6409. (or played) game with "Refresh (Local)" to reactivate normal
  6410. .B "xigc"
  6411. behavior.
  6412. .sp
  6413. By default, the "Save Moves" and "Save Current" menu items
  6414. will save the current game
  6415. in a human-readable text format.  However, you can specify that
  6416. games be saved in the machine-readable SGF format if you wish.
  6417. To use SGF format, include the line
  6418. .ti 10
  6419. .B
  6420. SAVEFORMAT sgf
  6421. .P
  6422. .br
  6423. in your
  6424. .B ".xigcrc"
  6425. file.  Use
  6426. .ti 10
  6427. .B
  6428. SAVEFORMAT text
  6429. .P
  6430. .br
  6431. for the default behavior.
  6432. .sp
  6433. The local command
  6434. .B "gameno"
  6435. takes a number that sets the current game within
  6436. .B "xigc."
  6437. For example, to look at a game when you have first started
  6438. .B "xigc,"
  6439. use the command
  6440. .B "gameno 2"
  6441. to set
  6442. .B "xigc"
  6443. for game 2, then click "Refresh (Host)" to
  6444. display the moves of that game.
  6445. When playing or observing, the game number
  6446. is tracked automatically.  That is, if you use the IGS commands
  6447. .B "observe, moves"
  6448. or
  6449. .B "match,"
  6450. you do not need to use
  6451. .B "gameno."
  6452. Another way to look at a game in progress without observing it is with the
  6453. .B "moves n"
  6454. command, where
  6455. .B "n"
  6456. is the number of the game you wish to look at.  When you use
  6457. .B "moves n,"
  6458. you can step through the game moves; you cannot use
  6459. .B "moves"
  6460. while you are observing or playing another game.
  6461. .sp
  6462. The local command
  6463. .B "observeoff"
  6464. will stop observing a game in progress, but is not needed
  6465. when the game ends or is adjourned.  You can only play or observe
  6466. one game; you cannot observe multiple games with
  6467. .B "xigc."
  6468. .sp
  6469. When a game you are playing is near the end, and players have
  6470. made the three required passes, IGS will prompt "Type done when
  6471. finished" to signal you are to remove dead stones.  To do this with
  6472. .B "xigc,"
  6473. just place the cursor over a stone you wish to remove, and click
  6474. the left mouse button.  The stones will be removed at IGS and locally
  6475. within
  6476. .B "xigc."
  6477. When you and your opponent have removed all the dead
  6478. stones, type "done" to have IGS to score the game and redraw the
  6479. final board position on the
  6480. .B "xigc"
  6481. board.  Note that he final "on-the-board" point count, including captures
  6482. and territory, will be shown in the "Captured" lines in the
  6483. .B "xigc"
  6484. menu.  This final count does not include any komi associated
  6485. with the game, and so is not the correct final score.
  6486. .sp
  6487. The "Quit" menu item will not work if you have used the
  6488. .B "-c"
  6489. command-line option, since
  6490. .B "xigc"
  6491. does not know how to exit cleanly from any random user-specified
  6492. communications command.  You must exit from each intermediate
  6493. system manually.
  6494. .SH "IGSCOMM"
  6495. .B "igscomm"
  6496. is a very simple replacement for
  6497. .B "telnet"
  6498. for communications to the IGS.  If possible, use
  6499. .B "igscomm"
  6500. instead of
  6501. .B "telnet"
  6502. as your communications program with
  6503. .B "xigc."
  6504. .B "igscomm"
  6505. can take the
  6506. .B "-h"
  6507. argument, followed by a host address, and the
  6508. .B "-p"
  6509. argument, followed by a port (socket) number at that host.  These
  6510. arguments are only needed if you are calling a machine other than
  6511. the default IGS.  You can also use the
  6512. .B "-e"
  6513. argument with
  6514. .B "igscomm"
  6515. if you are using it through an intermediate system (i.e., with the
  6516. .B "-c"
  6517. option of
  6518. .B "xigc.)"
  6519. The
  6520. .B "-e"
  6521. option turns off the extra echo otherwise seen with intermediate
  6522. systems.  For example:
  6523. .ti 10
  6524. .B
  6525. igscomm -e -h cnam.cnam.fr -p 6969
  6526. .P
  6527. .sp
  6528. Exit from
  6529. .B "igscomm"
  6530. by entering a single dot on a line.
  6531. .SH "CAVEATS"
  6532. This code may not work on X11R3 or older releases of X Window System,
  6533. or on some SVR3 systems on 386 machines.  It has been tested with
  6534. Sun (X11R4 and X11R5), 386/SVR4 (X11R5), DEC (UNIX and VMS), HP (and Apollo),
  6535. SGI, MIPS (X11R4), Convex, and IBM RS6000 (AIX 3.2) systems.
  6536. .sp
  6537. This is not a general purpose terminal emulator; it was designed to work
  6538. with the IGS.  Output lines from intermediate systems that begin with numbers
  6539. may be mangled by
  6540. .B "xigc."
  6541. .SH "ACKNOWLEDGEMENTS"
  6542. The go board was adapted from the "Goban Widget" by dumesnil@etca.fr.
  6543. Code for dead stone management was adapted from
  6544. adrian@u.washington.edu, and some pieces concerned with syntax of I/O
  6545. between the user and the IGS came from tcasey@leo.unm.edu.  Thanks
  6546. to several other users for contributing ideas and code fragments, especially
  6547. loganj@byu.edu.
  6548. .sp
  6549. The IGS is currently on the machine icsib18.icsi.berkeley.edu (128.32.201.46)
  6550. at port 6969.  Another server may be at cnam.cnam.fr (192.33.159.6).
  6551. .SH "AUTHOR"
  6552. S.Coffin     scoffin@uswest.com
  6553. .SH "BUGS"
  6554. .nf
  6555. .so README
  6556. .fi
  6557. SHAR_EOF
  6558. fi
  6559. exit 0
  6560. #    End of shell archive
  6561.